5

我有一个 Collection App.listingList,随后fetch()add:true.

App.listingList.fetch({
        data: {some:data},
        processData: true,
        add: true
});

问题:新添加的模型如何在不重新渲染现有模型的视图的情况下渲染它们的视图。这意味着我不能这样做:

this.collection.each( function(listing, index) {
    new ListingMarkerView({ model:listing }).render();
}, this);

尝试#1

在集合add事件上渲染视图,我无法找到一种方法来访问要渲染的新模型

ListingListView = Backbone.View.extend({

    initialize: function() {
        this.collection.bind('add', this.renderNew, this);
    },

    render: function() {
        console.log('render ListingListView');
        this.collection.each( function(listing, index) {
            new ListingMarkerView({ model:listing }).render();
        }, this);
        return this;
    },

    renderNew: function() {
        // How do I grab the new models?
        new ListingMarkerView({ model:listing }).render(); // wont work
        return this;
    }
});

尝试#2

我尝试使用第二个 Collection 来执行后续fetch操作,并使用 underscore.js 比较两个集合的模型_.without(),但返回的数组仍然包含在作为参数传递的第二个数组中找到的元素。Using_difference()还返回与第一个数组传递的相同数组。

App.listingListNew.fetch({
        data: {some:data},
        processData: true,
        success: function() {
            console.log(App.listingListNew.models);
            console.log(App.listingList.models);
            console.log(_.without(App.listingListNew.models, App.listingList.models));
            console.log(_.difference(App.listingListNew.models, App.listingList.models));
        }
});

console.log输出

由于我将 2 个相同的数组传入_.difference()and _.without(),因此输出应该是[]. 但它不是 :/ 也许是因为cid不同,所以它们中的每一个都被视为独一无二的?

在此处输入图像描述

4

2 回答 2

5

当您执行 acollection.bind('add', this.renderNew, this);时,它会自动将添加的模型作为参数传递给您的方法。

在您的方法中包含参数,您应该可以访问新模型。

renderNew: function(newModel) {
    new ListingMarkerView({ model:newModel }).render();
    return this;
}
于 2012-09-29T20:24:01.420 回答
0

我知道这是一个老问题,但我遇到了同样的问题并遇到了这个回复,所以我想我会添加一种替代方法。我不确定它的效率如何,但它确实有效。我正在使用它来支持无限滚动功能。

我使用的是 Backbone 1.2.1,所以在集合提取中,我使用的是这里的文档remove:false而不是弃用的:http add:true: //backbonejs.org/#Collection-fetch

基本方法是在首次渲染时为集合中的每个项目设置一个rendered属性,然后在后续提取时使用该属性忽略先前渲染的项目。true

型号及收藏:

MyApp.Item = Backbone.Model.extend({});

MyApp.ItemList = Backbone.Collection.extend({
model: MyApp.Item,
    url: '/api/item/',
    parse : function(response){
        if (response.stat) {
            return _.map(response.content, function(model, id) {
                model.id = id;
                return model;
            });
        }
    }
});

意见:

MyApp.ItemListView = Backbone.View.extend({
    tagName: 'ul',
    className: 'item-list',
    render: function() {
        this.collection.each(function(item){
            //don't render items that have already been rendered!
            if (!item.rendered) {
                var itemListDetailView = new MyApp.ItemListDetailView({model: item});
                this.$el.append(itemListDetailView.render().el);
                item.rendered = true;
            }
        }, this)
        return this;
    }
});

MyApp.ItemListDetailView = Backbone.View.extend({
    tagName: 'li',
    className: 'item-list-detail',
    render: function() {
        $(this.el).html( '<div class="item-title">' + this.model.get('title') + '</div>');
        return this;
    }
});

抓取功能:

MyApp.loadMyItems = function () {
    MyApp.gettingData = true;  //flag for infinite scroll
    MyApp.myItems.fetch({
        traditional: true,
        remove:false,
        data: {
            u_id: MyApp.User.id,
            order: 'create_date:desc',
            start: MyApp.myItems.length,
            num_items: 10
        },
        success: function(){
           MyApp.gettingData = false; //flag for infinite scroll
           MyApp.myItemsView.render();
        }
    });
};

来电:

//on initial page load
MyApp.myItems = new MyApp.ItemsCollection();
MyApp.myItemsView = new MyApp.ItemListView({
                            collection: MyApp.myItems, 
                            el: $('#my-items') 
                         });
MyApp.loadMyItems();

//infinite scroll
$('#items .infinite-scroll').on('loadmore', function () {
    if (!MyApp.gettingData) {
        MyApp.loadMyItems();
    } 
});
于 2015-08-01T14:06:33.973 回答