2017-05-03 124 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