Marionette 递增后显示新元素
Marionette Show new element after increment
我正在尝试查看每次从我的后端 (.fetch()
) 提取 20 种不同产品后,DOM 将显示一个产品广告。我 运行 遇到的问题是每次集合触发 add
事件时,都会重新呈现 CompositeView。
如何在不重新渲染整个父视图的情况下将子视图添加到 CompositeView?
define(["marionette", "lodash", "text!fonts/products/template.html",
'fonts/products/item-view', 'fonts/products/model', 'eventer'],
function(Marionette, _, templateHTML, ProductItemView, ProductsModel, eventer) {
'use strict';
var ProductsView = Marionette.CompositeView.extend({
template: _.template(templateHTML),
childView: ProductItemView,
childViewContainer: '.items',
productsLimit: 150,
initialize: function() {
this.listenTo(eventer, 'sort:products', this.sortCollection, this);
this.listenTo(this.collection, 'reset sort add', this.render, this);
this.listenTo(this.collection, 'sync', this.setupSync, this);
},
sortCollection: function(field) {
this.collection.sortByKey(field);
},
setupSync: function() {
this.setupWindowScrollListener();
this.render();
},
productsEnd: function() {
eventer.trigger('products:end');
},
setupWindowScrollListener: function() {
var $window = $(window),
$document = $(document),
that = this,
collectionSize = that.collection.length;
if(collectionSize <= that.productsLimit) {
$window.on('scroll', _.throttle(function() {
var scrollTop = $window.scrollTop(),
wHeight = $window.height(),
dHeight = $document.height(),
margin = 200;
if(scrollTop + wHeight > dHeight - margin) {
eventer.trigger('fetch:more:products');
$window.off('scroll');
}
}, 500));
} else {
that.productsEnd();
}
},
});
return ProductsView;
});
生成广告代码
这是我用来尝试生成广告的代码
https://gist.github.com/dennismonsewicz/aecf9bd0befe63e96ee6
导致您的父视图重新呈现的原因是您在集合添加事件上调用了 render
:)
this.listenTo(this.collection, 'reset sort add', this.render, this);
除非你真的想重新渲染父 CompositeView 你根本不需要这个监听器因为Marionette处理:
- collection#add: _onCollectionAdd 将在 default 中呈现和放置新的子视图(基于比较器,如果 none 则 id)排序
- collection#reset:Marionette 在您的 CompositeView 上已经有一个侦听器,如果您的集合是
reset
,它将为您调用 this.render
- collection#sort:如果您提供视图
{ sort: true }
作为 CompositeView 的选项,它将处理您集合中的 'sort'
事件。默认是对子视图进行排序,然后在 CompositeView 上调用 render
。如果您不希望您的 CompositeView 被重新渲染,传递 { reorderOnSort: true }
并且子视图将被有效地重新排序而无需重新渲染任何东西(父或子),只需按照 collection.comparator
. 指定的排序顺序移动子 DOM 元素
我正在尝试查看每次从我的后端 (.fetch()
) 提取 20 种不同产品后,DOM 将显示一个产品广告。我 运行 遇到的问题是每次集合触发 add
事件时,都会重新呈现 CompositeView。
如何在不重新渲染整个父视图的情况下将子视图添加到 CompositeView?
define(["marionette", "lodash", "text!fonts/products/template.html",
'fonts/products/item-view', 'fonts/products/model', 'eventer'],
function(Marionette, _, templateHTML, ProductItemView, ProductsModel, eventer) {
'use strict';
var ProductsView = Marionette.CompositeView.extend({
template: _.template(templateHTML),
childView: ProductItemView,
childViewContainer: '.items',
productsLimit: 150,
initialize: function() {
this.listenTo(eventer, 'sort:products', this.sortCollection, this);
this.listenTo(this.collection, 'reset sort add', this.render, this);
this.listenTo(this.collection, 'sync', this.setupSync, this);
},
sortCollection: function(field) {
this.collection.sortByKey(field);
},
setupSync: function() {
this.setupWindowScrollListener();
this.render();
},
productsEnd: function() {
eventer.trigger('products:end');
},
setupWindowScrollListener: function() {
var $window = $(window),
$document = $(document),
that = this,
collectionSize = that.collection.length;
if(collectionSize <= that.productsLimit) {
$window.on('scroll', _.throttle(function() {
var scrollTop = $window.scrollTop(),
wHeight = $window.height(),
dHeight = $document.height(),
margin = 200;
if(scrollTop + wHeight > dHeight - margin) {
eventer.trigger('fetch:more:products');
$window.off('scroll');
}
}, 500));
} else {
that.productsEnd();
}
},
});
return ProductsView;
});
生成广告代码 这是我用来尝试生成广告的代码 https://gist.github.com/dennismonsewicz/aecf9bd0befe63e96ee6
导致您的父视图重新呈现的原因是您在集合添加事件上调用了 render
:)
this.listenTo(this.collection, 'reset sort add', this.render, this);
除非你真的想重新渲染父 CompositeView 你根本不需要这个监听器因为Marionette处理:
- collection#add: _onCollectionAdd 将在 default 中呈现和放置新的子视图(基于比较器,如果 none 则 id)排序
- collection#reset:Marionette 在您的 CompositeView 上已经有一个侦听器,如果您的集合是
reset
,它将为您调用 - collection#sort:如果您提供视图
{ sort: true }
作为 CompositeView 的选项,它将处理您集合中的'sort'
事件。默认是对子视图进行排序,然后在 CompositeView 上调用render
。如果您不希望您的 CompositeView 被重新渲染,传递{ reorderOnSort: true }
并且子视图将被有效地重新排序而无需重新渲染任何东西(父或子),只需按照collection.comparator
. 指定的排序顺序移动子 DOM 元素
this.render