木偶在增量后显示新元素

时间:2015-07-09 04:28:11

标签: marionette

我试图查看从我的后端(.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

1 个答案:

答案 0 :(得分:2)

导致您的父视图重新渲染的原因是您在集合添加事件上调用render :)

this.listenTo(this.collection, 'reset sort add', this.render, this);

除非你真的想重新渲染那个父CompositeView,否则你根本不需要这个侦听器 ,因为Marionette处理:

  • collection#add:_onCollectionAdd将呈现并在默认中放置新的子视图(基于比较器,如果没有,则为id)排序顺序
  • collection#reset:如果您的收藏品是this.render
  • ,Marionette已经在您的CompositeView上有一个监听器,可以为您调用reset
  • collection#sort:如果您将视图{ sort: true }作为CompositeView的选项提供,它将处理您收藏中的'sort'个事件。默认设置是对子视图进行排序,然后在CompositeView上调用render。如果您希望重新渲染CompositeView,则传递{ reorderOnSort: true }并且子视图将被有效地重新排序,而无需重新渲染任何内容(父级或子级),只需移动子级排序顺序中的DOM元素由collection.comparator
  • 指定