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 元素