2015-07-10 63 views
0

我有以下代碼後會發生集合同步:木偶CompositeView中children.findByIndex工作不收集同步後如預期

adGeneration: function() { 
     var child = this.children.findByIndex(this.children.length - 1); 
     console.log(child.model.toJSON()); 
     eventer.trigger('generate:new:ad', child); 
    }, 

我遇到的問題是,在第一同步之後,該child元素是一個空白模型:

第一次:

Object {id: "5-vp39kv3uiigxecdi", size: 26, price: "9.84", face: "(⚆ _ ⚆)"}

每次經過:

Object {length: 40, models: Array[41], _byId: Object, _listeningTo: Object, _listenId: "l14"…}

ProductsCollection

define(["backbone", "lodash", "fonts/products/model", "eventer"], 
function(Backbone, _, ProductModel, eventer) { 
    'use strict'; 

    var ProductsCollection = Backbone.Collection.extend({ 
     model: ProductModel, 

     sort_key: 'price', 

     url: '/api/products', 

     offset: 0, 

     initialize: function() { 
      this.listenTo(eventer, 'fetch:more:products', this.loadMore, this); 
     }, 

     comparator: function(item) { 
      return item.get(this.sort_key); 
     }, 

     sortByKey: function(field) { 
      this.sort_key = field; 
      this.sort(); 
     }, 

     parse: function(data) { 
      return _.chain(data) 
        .filter(function(item) { 
         if(item.id) { 
          return item; 
         } 
        }) 
        .map(function(item){ 
         item.price = this.formatCurrency(item.price); 

         return item; 
        }.bind(this)) 
        .value(); 
     }, 

     formatCurrency: function(total) { 
      return (total/100).toFixed(2); 
     }, 

     loadMore: function() { 
      this.offset += 1; 
      this.fetch({ 
       data: { 
        limit: 20, 
        skip: this.offset 
       }, 
       remove: false, 
       success: function(collection) { 
        this.add(collection); 
       }.bind(this) 
      }); 
     } 
    }); 

    return ProductsCollection; 

}); 

LayoutView包含該作品收藏觀。收集是layoutview的牽強昂秀

define(["marionette", "lodash", "text!fonts/template.html", 
"fonts/controls/view", "fonts/products/view", "fonts/products/collection", "eventer"], 
function(Marionette, _, templateHTML, ControlsView, ProductsView, 
    ProductsCollection, eventer) { 
    'use strict'; 

    var FontsView = Marionette.LayoutView.extend({ 

     regions: { 
      controls: '#controls', 
      products: '#products-list' 
     }, 

     template: _.template(templateHTML), 

     initialize: function() { 
      this._controlsView = new ControlsView(); 
      this._productsView = new ProductsView({ 
       collection: new ProductsCollection({ 
        reorderOnSort: false, 
        sort: false 
       }) 
      }); 

      this.listenTo(this._productsView.collection, 'sync', this.loading, this); 
      this.listenTo(eventer, 'fetch:more:products', this.loading, this); 
      this.listenTo(eventer, 'products:end', this.productsEnd, this); 
     }, 

     onRender: function() { 
      this.getRegion('controls').show(this._controlsView); 
      this.getRegion('products').show(this._productsView); 
      this.loading(); 
     }, 

     onShow: function() { 
      this._productsView.collection.fetch({ 
       data: { 
        limit: 20 
       } 
      }) 
     }, 

     productsEnd: function() { 
      this.loading(); 
      this.$el.find('#loading').html("~ end of catalogue ~") 
     }, 

     loading: function() { 
      var toggle = this.$el.find('#loading').is(':hidden'); 
      this.$el.find('#loading').toggle(toggle); 
     } 
    }); 

    return FontsView; 

}); 

AdsView:

define(["marionette", "lodash", "text!ads/template.html", "eventer"], 
function(Marionette, _, templateHTML, eventer) { 
    'use strict'; 

    var AdsView = Marionette.ItemView.extend({ 
     template: _.template(templateHTML), 

     ui: { 
      ad: '.ad' 
     }, 

     initialize: function() { 
      this.listenTo(eventer, 'generate:new:ad', this.generateNewAd, this); 
     }, 

     onShow: function() { 
      // Set add image onShow 
      this.ui.ad.prop('src', '/ad/' + this.randomNumber()); 
     }, 

     generateNewAd: function(childView) { 
      var newAd = this.ui.ad.clone(), 
       element = childView.$el, 
       elementId = childView.model.get("id"); 

      newAd.prop('src', '/ad/' + this.randomNumber()); 

      $("#" + elementId).after(newAd); 
     }, 

     randomNumber: function() { 
      return Math.floor(Math.random()*1000); 
     }, 

     setUpAd: function() { 
      this.ui.ad.prop('src', '/ad/' + this.randomNumber()); 
     } 
    }); 

    return AdsView; 
}); 
+0

你可以發表1.請問在哪裏調用fetch,2.請問'collection'的定義? – seebiscuit

+1

這聽起來很奇怪(可能不會是修復),但是你可以用'this.children.last()'替換'this.children.findByIndex(this.children.length - 1)'。 findByIndex()有一個問題(見[保姆#49](https://github.com/marionettejs/backbone)。保姆/問題/ 49)) – seebiscuit

+0

@seebiscuit - 更新的問題與代碼。我嘗試了'this.children.last()',但仍然得到了同樣的結果:/ – dennismonsewicz

回答