2017-05-03 140 views
-1

我的backbone.js代碼有什麼問題?
當一個產品頁面加載僅顯示模式的默認值...
雖然在控制檯我看到正確的數據...

這裏是我的模型:模型視圖只顯示默認值

var app = app || {}; 
app.Product = Backbone.Model.extend({ 
    defaults: { 
     coverImage: 'img/placeholder.png', 
     id: null, 
     name: 'Unknown', 
     price: '100' 
    } 
}); 

收藏:

var app = app || {}; 
app.ProductList = Backbone.Collection.extend({ 
    model: app.Product, 
    url: 'php/listProducts.php' 
}); 

還有就是我的觀點:

var app = app || {}; 
app.ProductItemView = Backbone.View.extend({ 
    template: _.template($('#productPage').html()), 

    initialize: function(options) { 
     var id = options.id; 
     this.model = new app.Product(); 
     this.collection = new app.ProductList(); 
     this.collection.fetch({ 
      success: function(collection){ 
       console.log(collection.toJSON()); 
       console.log('Collection models: ', collection.models[id-1]); 
       this.model = collection.models[id-1]; 
       console.log('This model: ', this.model); 
      } 
     }); 

     this.render(); 
    }, 

    render: function() { 
     this.$el.html(this.template(this.model.attributes)); 
     return this; 
    } 


}); 

路由器:

var app = app || {}; 
app.Router = Backbone.Router.extend({ 
    routes: { 
     "product/:id": "productPageShow" 
    }, 

    initialize: function() { 
     this.$content = $("#product-list"); 
    }, 

    productPageShow: function(id) { 
     app.prodItView = new app.ProductItemView({ id: id }); 
     this.$content.html(app.prodItView.el); 
    } 

}); 

$(function() { 
    new app.Router(); 
    Backbone.history.start(); 
}); 

我的模板:

<div class="container">  
    <div id="product-list"></div> 
</div> 

<script id="productPage" type="text/template"> 
    <div> 
     <img src="<%= coverImage %>" class="img-responsive" style="width:100%" alt="<%= name %>"> 
    </div> 
    <div> 
     <h2><%= name %></h2> 
    </div> 
    <div> 
     <h3><%= price %></h3> 
    </div> 
</script> 

控制檯圖像:

console image

+0

可能的重複[Backbone:從服務器獲取的數據不顯示在視圖上](http://stackoverflow.com/questions/15330013/backbone-fetched-data-from-server-not-在視圖中顯示) –

回答

1

這是因爲 '獲取' 是一個異步操作,因此render()總是將success()回調之前調用撥打fetch()

一些額外的資源,如果你想:

https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started

http://backbonejs.org/#Model-fetch

要在你的代碼視覺上解釋執行的順序在initialize方法:

var app = app || {}; 
app.ProductItemView = Backbone.View.extend({ 
    template: _.template($('#productPage').html()), 

    initialize: function(options) { 
     // 1 
     var id = options.id; 
     // 2 
     this.model = new app.Product(); 
     // 3 
     this.collection = new app.ProductList(); 
     // 4 - fetch is only called and ajax request is sent to your backend. 
     //  success callback is still not called 
     this.collection.fetch({ 
      success: function(collection) { 
       // 6 - when you get the data from the server the callback is called 
       //  but the page is already rendered at this time 
       console.log(collection.toJSON()); 
       console.log('Collection models: ', collection.models[id-1]); 
       this.model = collection.models[id-1]; 
       console.log('This model: ', this.model); 
      } 
     }); 

     // 5 
     this.render(); 
    }, 

    render: function() { 
     this.$el.html(this.template(this.model.attributes)); 
     return this; 
    } 
}); 

的修補程序應該相當平凡,只需在成功回調的底部調用render方法即可d綁定到視圖的正確的上下文:

var app = app || {}; 
app.ProductItemView = Backbone.View.extend({ 
    template: _.template($('#productPage').html()), 

    initialize: function(options) { 
     var id = options.id; 
     this.model = new app.Product(); 
     this.collection = new app.ProductList(); 
     this.collection.fetch({ 
      success: _.bind(function(collection) { 
       console.log(collection.toJSON()); 
       console.log('Collection models: ', collection.models[id-1]); 
       this.model = collection.models[id-1]; 
       console.log('This model: ', this.model); 

       // Moved render call here 
       this.render(); 
      }, this) 
     }); 

    }, 

    render: function() { 
     this.$el.html(this.template(this.model.attributes)); 
     return this; 
    } 
}); 

而且,就像一般建議..從來沒有從集合挑款直接..使用提供get方法的集合,並通過模型id你需要..使用collection.get(mnodelId)而不是collection.models[arrayIndexOfTheModel]

+0

馬里奧非常感謝您的回答和建議!有用! – Vovix

+1

'.fetch'函數可以使用'context'選項,避免使用'_.bind'。 –

+0

@EmileBergeron - 這的確是對的。在我與Backbone一起工作的所有年中,我都沒有注意到這一點。它不在文檔中,我現在只在源代碼中確認它。這很奇怪,因爲'context'通常是作爲最後一個參數傳遞的,沒有那麼簡單!謝謝 :) – Mario