CollectionView - collection 数据未传递给 childView
CollectionView - collection data not being passed to childView
我正在尝试让 collectionView 工作,但我不太确定 CollectionView 是否自动启动 fetch 方法然后填充 ChildViews与获取的数据。或者这是我需要手动做的事情吗?我查看了 Marionette 文档页面,但找不到任何合适的示例来回答我的问题。
下面的例子是我到目前为止得到的,collection 填满了所有需要的数据,但由于某种原因数据没有传递给子视图。
每当我调用'http://localhost/GetCategories'时返回下面的JSON:
JSON数据:
[{"category_id":"Category1","category_name":"Category One"},
{"category_id":"Category2","category_name":"Category Two"}]
collection:
define([ 'underscore', 'backbone', 'models/MainMenu/MM.model.category'], function(_, Backbone, m_Category){
var CategoriesCollection = Backbone.Collection.extend({
model: m_Category,
url : 'GetCategories';
initialize: function() {
console.log('CategoriesCollection initialized...');
this.fetch()
}
});
return CategoriesCollection;
});
collection查看:
define([ 'backbone', 'underscore', 'marionette',
'collections/MainMenu/collection.categories' ,
'layouts/MainMenu/itemview.category'],
function (Backbone, _, Marionette, c_Categories, iv_Category) {
"use strict";
var CategoriesCollectionView = Marionette.CollectionView.extend({
tagName: 'div',
template: null,
id: 'categories',
childView: iv_Category,
collection : new c_Categories(),
initialize: function(){
console.log('Categories Collection: initialized');
/// or should I call fetch() from within the CV?
/// but how do I then pass all the data to ChildView?
this.collection.fetch().done(function(){
})
},
onRender: function(){
console.log(this.collection) ///<-- shows all the JSON data properly
},
onShow: function(){
}
});
return CategoriesCollectionView;
});
项目视图:
define([ 'backbone', 'underscore', 'marionette', 'templates/template.mainmenu'], function (Backbone, _, Marionette, template) {
"use strict";
var CategoryView = Marionette.ItemView.extend({
tagName: 'div',
template: template['category.layout'],
id: 'category-layout',
initialize: function(){
console.log('Category Layout: initialized');
},
onRender: function(){
console.log(this.model) /// < --- doesn't return anything
},
onShow: function(){
console.log(this.model) ///< --- doesn't return anything
}
});
return CategoryView;
});
它仅在我在 CollectionView 之上创建 LayoutView 并从那里处理获取和分配 collection 时才有效。
define([ 'backbone', 'underscore', 'marionette',
'templates/template.mainmenu',
'collections/MainMenu/MM.collection.categories',
'layouts/MainMenu/collectionview.categories' ],
function (Backbone, _, Marionette, template, c_Categories, cv_Categories) {
"use strict";
var CategoryLayoutView = Marionette.LayoutView.extend({
template: template['categories.layout'],
regions: {
categories : '#categories'
},
id: 'categories-layout',
initialize: function(options){
this.collection = new c_Categories();
console.log('Category Layout: initialized');
},
onRender: function(){
var categories = this.categories
var collection = this.collection;
collection.fetch().done(function(cData){
categories.show(new cv_Categories({collection : collection}))
})
},
onShow: function(){
}
});
return CategoryLayoutView;
});
如有任何帮助,我们将不胜感激。
谢谢
You need to pass childViewOptions from your collection view.
示例:
define([ 'backbone', 'underscore', 'marionette',
'collections/MainMenu/collection.categories' ,
'layouts/MainMenu/itemview.category'],
function (Backbone, _, Marionette, c_Categories, iv_Category) {
"use strict";
var CategoriesCollectionView = Marionette.CollectionView.extend({
tagName: 'div',
template: null,
id: 'categories',
childView: iv_Category,
collection : new c_Categories(),
childViewOptions : function(){
return{
collection: this.collection
}
},
initialize: function(){
console.log('Categories Collection: initialized');
/// or should I call fetch() from within the CV?
/// but how do I then pass all the data to ChildView?
this.collection.fetch().done(function(){
})
},
onRender: function(){
console.log(this.collection) ///<-- shows all the JSON data properly
},
onShow: function(){
}
});
return CategoriesCollectionView;
});
并且在您的项目视图中,您可以在初始化方法中获取从集合视图传递的每个集合模型。
项目视图中的初始化方法示例:
initialize: function(options){
console.log('Category Layout: initialized');
console.log(options.model);
},
Marionette.CollectionView 示例 - jsfiddle
//Collection View
var CollectionView = Marionette.CollectionView.extend({
template: "#coll-template",
childView: MainView,
itemViewContainer: "#items"
});
//Item View
var MainView = Marionette.ItemView.extend({
template: "#sample-template",
templateHelpers: function() {
return {
id: this.model.id
};
},
onDomRefresh: function() {
console.log("DOM REFRESH OF ITEM");
}
});
//Creating some models
var model = new Backbone.Model({
contentPlacement: "here",
id: 1
});
var model2 = new Backbone.Model({
contentPlacement: "here",
id: 2
});
var model3 = new Backbone.Model({
contentPlacement: "here",
id: 3
});
//Create collection and resetting it with created models
var collection = new Backbone.Collection();
collection.reset([model, model2, model3]);
var view = new CollectionView({
collection: collection
});
Prelimnaries:Collection/CompositeView 的主要目的是正确呈现 Backbone.Collection,即将集合模型传递给 CollectionView children ,并渲染那些 children。除了提供 Collection/CompositeView 之外,您没有必要参与——这是关键——一个 pre 填充的集合。
现在,您遇到的问题是您在 CategoriesCollection.initialize()
上执行异步获取(默认情况下所有 AJAX 调用都是异步的)。由于在定义 CategoriesCollectionView
时会调用该初始化(请参阅其 collection
属性),因此在呈现它时提取可能不会及时返回。因此,CollectionView 呈现,但没有找到模型,如果提供了模型,则只呈现 emptyView
。
你有两个选择:在 LayoutView 中做你正在做的事情(这不仅是我在我的视图中经常做的事情,而且我已经和一些人谈过顶级 Marionette 贡献者,他们也这样做),或同步获取(出于性能原因我不推荐这样做)。
一些提示
从 CategoriesCollection.initialize()
中删除提取(如果你想保留它,你必须在提取中传递选项 { async: false }
,以保证数据将在呈现视图时返回。但是,我不建议这样做,因为在等待获取时会阻塞 CPU。
从 CategoriesCollectionView
定义中删除 CategoriesCollectionView.collection
属性。相反,我们将从 parent LayoutView
中传递集合
我建议您使用 .then()
而不是 .done()
作为 Promise 处理程序。两个原因:
一个。 .then()
更好地处理错误:如果错误不受管理,它将显示堆栈跟踪,并且第二个参数始终可用于实际处理由 Promise 导致的错误。
b. .then()
允许您继续链接。也许不在这个调用中,但在其他一些 Promise 中,您可能希望在调用进入后调用一系列回调。顾名思义,.done()
是回调链的末端
除此之外,您的解决方案是最佳实践。
我正在尝试让 collectionView 工作,但我不太确定 CollectionView 是否自动启动 fetch 方法然后填充 ChildViews与获取的数据。或者这是我需要手动做的事情吗?我查看了 Marionette 文档页面,但找不到任何合适的示例来回答我的问题。
下面的例子是我到目前为止得到的,collection 填满了所有需要的数据,但由于某种原因数据没有传递给子视图。
每当我调用'http://localhost/GetCategories'时返回下面的JSON:
JSON数据:
[{"category_id":"Category1","category_name":"Category One"},
{"category_id":"Category2","category_name":"Category Two"}]
collection:
define([ 'underscore', 'backbone', 'models/MainMenu/MM.model.category'], function(_, Backbone, m_Category){
var CategoriesCollection = Backbone.Collection.extend({
model: m_Category,
url : 'GetCategories';
initialize: function() {
console.log('CategoriesCollection initialized...');
this.fetch()
}
});
return CategoriesCollection;
});
collection查看:
define([ 'backbone', 'underscore', 'marionette',
'collections/MainMenu/collection.categories' ,
'layouts/MainMenu/itemview.category'],
function (Backbone, _, Marionette, c_Categories, iv_Category) {
"use strict";
var CategoriesCollectionView = Marionette.CollectionView.extend({
tagName: 'div',
template: null,
id: 'categories',
childView: iv_Category,
collection : new c_Categories(),
initialize: function(){
console.log('Categories Collection: initialized');
/// or should I call fetch() from within the CV?
/// but how do I then pass all the data to ChildView?
this.collection.fetch().done(function(){
})
},
onRender: function(){
console.log(this.collection) ///<-- shows all the JSON data properly
},
onShow: function(){
}
});
return CategoriesCollectionView;
});
项目视图:
define([ 'backbone', 'underscore', 'marionette', 'templates/template.mainmenu'], function (Backbone, _, Marionette, template) {
"use strict";
var CategoryView = Marionette.ItemView.extend({
tagName: 'div',
template: template['category.layout'],
id: 'category-layout',
initialize: function(){
console.log('Category Layout: initialized');
},
onRender: function(){
console.log(this.model) /// < --- doesn't return anything
},
onShow: function(){
console.log(this.model) ///< --- doesn't return anything
}
});
return CategoryView;
});
它仅在我在 CollectionView 之上创建 LayoutView 并从那里处理获取和分配 collection 时才有效。
define([ 'backbone', 'underscore', 'marionette',
'templates/template.mainmenu',
'collections/MainMenu/MM.collection.categories',
'layouts/MainMenu/collectionview.categories' ],
function (Backbone, _, Marionette, template, c_Categories, cv_Categories) {
"use strict";
var CategoryLayoutView = Marionette.LayoutView.extend({
template: template['categories.layout'],
regions: {
categories : '#categories'
},
id: 'categories-layout',
initialize: function(options){
this.collection = new c_Categories();
console.log('Category Layout: initialized');
},
onRender: function(){
var categories = this.categories
var collection = this.collection;
collection.fetch().done(function(cData){
categories.show(new cv_Categories({collection : collection}))
})
},
onShow: function(){
}
});
return CategoryLayoutView;
});
如有任何帮助,我们将不胜感激。
谢谢
You need to pass childViewOptions from your collection view.
示例:
define([ 'backbone', 'underscore', 'marionette',
'collections/MainMenu/collection.categories' ,
'layouts/MainMenu/itemview.category'],
function (Backbone, _, Marionette, c_Categories, iv_Category) {
"use strict";
var CategoriesCollectionView = Marionette.CollectionView.extend({
tagName: 'div',
template: null,
id: 'categories',
childView: iv_Category,
collection : new c_Categories(),
childViewOptions : function(){
return{
collection: this.collection
}
},
initialize: function(){
console.log('Categories Collection: initialized');
/// or should I call fetch() from within the CV?
/// but how do I then pass all the data to ChildView?
this.collection.fetch().done(function(){
})
},
onRender: function(){
console.log(this.collection) ///<-- shows all the JSON data properly
},
onShow: function(){
}
});
return CategoriesCollectionView;
});
并且在您的项目视图中,您可以在初始化方法中获取从集合视图传递的每个集合模型。
项目视图中的初始化方法示例:
initialize: function(options){
console.log('Category Layout: initialized');
console.log(options.model);
},
Marionette.CollectionView 示例 - jsfiddle
//Collection View
var CollectionView = Marionette.CollectionView.extend({
template: "#coll-template",
childView: MainView,
itemViewContainer: "#items"
});
//Item View
var MainView = Marionette.ItemView.extend({
template: "#sample-template",
templateHelpers: function() {
return {
id: this.model.id
};
},
onDomRefresh: function() {
console.log("DOM REFRESH OF ITEM");
}
});
//Creating some models
var model = new Backbone.Model({
contentPlacement: "here",
id: 1
});
var model2 = new Backbone.Model({
contentPlacement: "here",
id: 2
});
var model3 = new Backbone.Model({
contentPlacement: "here",
id: 3
});
//Create collection and resetting it with created models
var collection = new Backbone.Collection();
collection.reset([model, model2, model3]);
var view = new CollectionView({
collection: collection
});
Prelimnaries:Collection/CompositeView 的主要目的是正确呈现 Backbone.Collection,即将集合模型传递给 CollectionView children ,并渲染那些 children。除了提供 Collection/CompositeView 之外,您没有必要参与——这是关键——一个 pre 填充的集合。
现在,您遇到的问题是您在 CategoriesCollection.initialize()
上执行异步获取(默认情况下所有 AJAX 调用都是异步的)。由于在定义 CategoriesCollectionView
时会调用该初始化(请参阅其 collection
属性),因此在呈现它时提取可能不会及时返回。因此,CollectionView 呈现,但没有找到模型,如果提供了模型,则只呈现 emptyView
。
你有两个选择:在 LayoutView 中做你正在做的事情(这不仅是我在我的视图中经常做的事情,而且我已经和一些人谈过顶级 Marionette 贡献者,他们也这样做),或同步获取(出于性能原因我不推荐这样做)。
一些提示
从
CategoriesCollection.initialize()
中删除提取(如果你想保留它,你必须在提取中传递选项{ async: false }
,以保证数据将在呈现视图时返回。但是,我不建议这样做,因为在等待获取时会阻塞 CPU。从
CategoriesCollectionView
定义中删除CategoriesCollectionView.collection
属性。相反,我们将从 parent LayoutView 中传递集合
我建议您使用
.then()
而不是.done()
作为 Promise 处理程序。两个原因:一个。
.then()
更好地处理错误:如果错误不受管理,它将显示堆栈跟踪,并且第二个参数始终可用于实际处理由 Promise 导致的错误。 b..then()
允许您继续链接。也许不在这个调用中,但在其他一些 Promise 中,您可能希望在调用进入后调用一系列回调。顾名思义,.done()
是回调链的末端
除此之外,您的解决方案是最佳实践。