【问题标题】:Backbone.js: After doing Fetch(), render only the new modelsBackbone.js:执行 Fetch() 后,仅渲染新模型
【发布时间】:2012-09-29 19:46:30
【问题描述】:

我有一个集合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

我尝试使用第二个集合来执行后续的fetch,并使用 underscore.js 的_.without() 比较两个集合的模型,但返回的数组仍然包含在作为参数传递的第二个数组中找到的元素.使用_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()_.without(),因此输出应该是 []。但它不是:/ 可能是因为cid 不同,所以每一个都被视为唯一?

【问题讨论】:

    标签: javascript jquery backbone.js underscore.js


    【解决方案1】:

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

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

    renderNew: function(newModel) {
        new ListingMarkerView({ model:newModel }).render();
        return this;
    }
    

    【讨论】:

      【解决方案2】:

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

      我使用的是 Backbone 1.2.1,因此在集合提取中,我使用 remove:false 而不是已弃用的 add:true,这里的文档:http://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();
          } 
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-18
        • 2016-06-09
        • 1970-01-01
        • 2013-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-30
        相关资源
        最近更新 更多