Javascript 将JSon对象传递给木偶复合视图
我有一个显示对象列表的简单表格,但是我想传递一个布尔值,这样,如果用户登录后可以看到[edit]按钮,我已经尝试将参数作为listItem传递,但无法,有人能解释一下吗 澄清:我希望能够从模板内部访问该值Javascript 将JSon对象传递给木偶复合视图,javascript,json,backbone.js,marionette,Javascript,Json,Backbone.js,Marionette,我有一个显示对象列表的简单表格,但是我想传递一个布尔值,这样,如果用户登录后可以看到[edit]按钮,我已经尝试将参数作为listItem传递,但无法,有人能解释一下吗 澄清:我希望能够从模板内部访问该值 var TableView = {}; TableView.RowItemView = Marionette.ItemView.extend({ tagName: "tr", template:$('#table-template-ite
var TableView = {};
TableView.RowItemView = Marionette.ItemView.extend({
tagName: "tr",
template:$('#table-template-item').html(),
//if required add events and triggers here.
events: {
"click td a.js-show": "showClicked",
"click td a.js-edit": "editClicked"
}
});
TableView.MainTable = Marionette.CompositeView.extend({
tagName: "table",
className: "table table-hover",
template: $('#table-template').html() ,
itemView: TableView.RowItemView,
itemViewContainer: "tbody"
});
return TableView;
InitialController.home = function () {
console.log("initializing application layout");
var list = new PropertiesModel.ContactCollection;
list.fetch({reset: true});
var tableView = new TableView.MainTable({
collection: list
});
app.mainRegion.show(tableView);
};
我假设您的应用程序中有某个地方可以知道用户是否登录。为了便于论证,我将假定它封装在一个附加到用户对象的函数中,而用户对象又附加到全局应用,因此
MyApp.CurrentUser.isLoggedIn()
您可以采取的一种方法是在RowItemView
和该CurrentUser
对象之间添加依赖项。渲染行项目视图时
测试用户是否登录并相应更新视图
我在这里对您的代码做了很多假设,但这段代码应该演示一下基本思想:
onRender: function() {
if (MyApp.CurrentUser.isLoggedIn()) {
this.$('.js-edit').removeClass('hidden');
}
}
附录
那么,您想更新视图的多个部分吗?尝试使用templateHelpers属性:
TableView.RowItemView = Marionette.ItemView.extend({
template: /* resolves to: */ '<td><%= getItemOne() %></td>' +
'<td><%= getItemTwo() %></td>',
templateHelpers: {
getItemOne: function() {
if (window.isLoggedIn) {
return 'Logged In Content';
}
return 'Not Logged In Content';
},
getItemTwo: function() {
if (window.isLoggedIn) {
return 'Logged In Content';
}
return 'Not Logged In Content';
}
}
这种方法的问题是,您正在从CompositeView传递一个变量,这意味着您需要覆盖CompositeView的buildItemView
属性,坦率地说,这似乎比它的价值更大,但如果您想尝试它,这里有一个小提示:
TableView.MainTable = Marionette.CompositeView.extend({
initialize: function(collection, options) {
this.isLoggedIn = options.isLoggedIn;
// ...
},
buildItemView: function(item, ItemViewType, itemViewOptions){
var options = _.extend({model: item, isLoggedIn: this.isLoggedIn }, itemViewOptions);
return new ItemViewType(options);
},
我假设您的应用程序中有某个地方可以知道用户是否登录。为了便于论证,我将假定它封装在一个附加到用户对象的函数中,而用户对象又附加到全局应用,因此
MyApp.CurrentUser.isLoggedIn()
您可以采取的一种方法是在RowItemView
和该CurrentUser
对象之间添加依赖项。渲染行项目视图时
测试用户是否登录并相应更新视图
我在这里对您的代码做了很多假设,但这段代码应该演示一下基本思想:
onRender: function() {
if (MyApp.CurrentUser.isLoggedIn()) {
this.$('.js-edit').removeClass('hidden');
}
}
附录
那么,您想更新视图的多个部分吗?尝试使用templateHelpers属性:
TableView.RowItemView = Marionette.ItemView.extend({
template: /* resolves to: */ '<td><%= getItemOne() %></td>' +
'<td><%= getItemTwo() %></td>',
templateHelpers: {
getItemOne: function() {
if (window.isLoggedIn) {
return 'Logged In Content';
}
return 'Not Logged In Content';
},
getItemTwo: function() {
if (window.isLoggedIn) {
return 'Logged In Content';
}
return 'Not Logged In Content';
}
}
这种方法的问题是,您正在从CompositeView传递一个变量,这意味着您需要覆盖CompositeView的buildItemView
属性,坦率地说,这似乎比它的价值更大,但如果您想尝试它,这里有一个小提示:
TableView.MainTable = Marionette.CompositeView.extend({
initialize: function(collection, options) {
this.isLoggedIn = options.isLoggedIn;
// ...
},
buildItemView: function(item, ItemViewType, itemViewOptions){
var options = _.extend({model: item, isLoggedIn: this.isLoggedIn }, itemViewOptions);
return new ItemViewType(options);
},
您可以将
ItemViewOptions
作为函数(动态)或对象(静态)提供给复合/集合视图渲染出的每个itemviews
在集合视图中设置后
/组合视图
,您可以通过在项目视图中执行以下操作来获取它们:
initialize: function(options){
var x = options.isLoggedIn;
}
编辑:或,在模板中查看它
您可以将ItemViewOptions
作为函数(动态)或对象(静态)提供给复合/集合视图渲染出的每个itemviews
在集合视图中设置后
/组合视图
,您可以通过在项目视图中执行以下操作来获取它们:
initialize: function(options){
var x = options.isLoggedIn;
}
编辑:或,在模板中查看它
似乎每一行都是可编辑的或不可编辑的。因此,这里有另一个答案,我认为更适合你的需要。它将防止您必须在每个ItemView
中传递选项和执行逻辑,但需要使用另一种视图类型
TableView.RowItemView = Marionette.ItemView.extend({
template:'#table-template-item',
//...snip
});
TableView.EditableRowItemView = TableView.RowItemView.extend({
template:'#editable-table-template-item',
});
TableView.MainTable = Marionette.CompositeView.extend({
initialize: function(){
if(isLoggedIn){ //true/false
this.itemView = TableView.EditableRowItemView
}
},
itemView: TableView.RowItemView
}
EditableRowItemView
扩展自TableView.RowItemView
,因为它们的逻辑基本相同,但使用不同的模板(可能还有一些额外的编辑逻辑)似乎每一行都可以编辑或不可编辑。因此,这里有另一个答案,我认为更适合你的需要。它将防止您必须在每个ItemView
中传递选项和执行逻辑,但需要使用另一种视图类型
TableView.RowItemView = Marionette.ItemView.extend({
template:'#table-template-item',
//...snip
});
TableView.EditableRowItemView = TableView.RowItemView.extend({
template:'#editable-table-template-item',
});
TableView.MainTable = Marionette.CompositeView.extend({
initialize: function(){
if(isLoggedIn){ //true/false
this.itemView = TableView.EditableRowItemView
}
},
itemView: TableView.RowItemView
}
EditableRowItemView
扩展自TableView.RowItemView
,因为它们的逻辑基本相同,但具有不同的模板(可能还有一些额外的编辑逻辑)你好,chris,是的,我有一个全局变量,用于说明用户是否登录,问题是我想要一个有几个语句的模板,但是我将我的模型传递给了rowItemView,所以我不知道如何将我的用户对象传递给它。您是否尝试过使用templateHelpers
?我将用一个例子更新我的答案。你好,chris,是的,我有一个全局变量,说明用户是否登录,问题是我希望有一个包含一些语句的模板,但是我将模型传递给rowItemView,所以我不知道如何将我的用户对象传递给它。啊。您是否尝试过使用templateHelpers
?我将用一个例子更新我的答案。你好,Scott,我尝试过类似的方法,问题是我无法将该值传递给我的模板,当我尝试访问模板上的isLogged时,我会收到错误消息,即它未定义。您需要将isLoggedIn
变量放入模型中,以便模板引擎读取它(this.model.set('isLoggedIn',options.isLoggedIn | | false)
)。如果是这种情况,那么您可能希望在CompositeView
/CollectionView
中执行此操作,并放弃itemViewOptions。由您决定!此外,木偶网具有内置功能,只需提供一个字符串即可处理模板。因此,与其编写模板:$(“#表模板”)。html()
您只需编写模板:#表模板“
我反对在模型中添加isLoggedIn
属性,因为它可能会打破关注点的分离-例如,如果模型描述了一个产品,那么它对产品
模式没有实际意义