backbone.js视图在获取模型之前渲染
我正在尝试制作一个小型的backbone.js应用程序,但却在与事情的顺序作斗争 在我的html文件中,标题中有两个脚本块:backbone.js视图在获取模型之前渲染,backbone.js,Backbone.js,我正在尝试制作一个小型的backbone.js应用程序,但却在与事情的顺序作斗争 在我的html文件中,标题中有两个脚本块: <script type="text/template" id="model-template"> <a href="#"><%= title %></a> </script> <script type="text/javascript"> jQuery(function(){ wi
<script type="text/template" id="model-template">
<a href="#"><%= title %></a>
</script>
<script type="text/javascript">
jQuery(function(){
window.model.fetch();
});
</script>
该应用程序由一个简单的sinatra应用程序提供服务。url/mymodel
提供一个静态json文件:
{
"title": "My Model",
}
加载应用程序时,javascript控制台中出现错误:
Uncaught ReferenceError: title is not defined
问题似乎是,视图在从服务器获取模型之前呈现自身。为什么会这样?
昨天,我关注了PeepCode的前两个backbone.js屏幕广播。我试着将我的应用程序与来自屏幕广播的应用程序进行比较,但看不出我的应用程序需要工作的原因
有什么建议吗 您始终可以使用“默认”选项设置默认标题: 从服务器重置模型的状态。如果模型具有 从未填充过数据,或者如果您希望确保 具有最新的服务器状态。如果发生以下情况,将触发“更改”事件: 服务器的状态与当前属性不同。接受 选项散列中的成功和错误回调,已传递 (模型、响应)作为参数 在本例中,您将希望在成功回调中呈现视图
model.fetch({
error: function () {
},
success: function (model, response) { // model is ready now
// do view stuff here
}
});
在这种情况下,您应该引导您的模型数据,以便它在页面加载时可用 而不是
window.model.fetch();
将类似的内容放入(如果使用.erb)
或者处理模型的成功。获取并渲染视图
window.model.fetch({
success: function (model, response) {
window.MyApp.myModelView.render();
}
});
显然,从前面的回答中,您知道需要在fetchsuccess回调上进行渲染,但是我认为您的问题远不止这些。也就是说,主路径用于立即构建myModelView,而不是在其数据加载时。之所以发生这种情况,是因为您正在调用render()以便将其附加到正文中。相反,请尝试使用现有元素初始化视图。通过这种方式,您可以延迟对render的调用,直到fetch完成:
window.MyApp = Backbone.Router.extend({
routes: {
'': 'home'
},
initialize: function () {
},
home: function() {
var $body = $(document.body).empty();
var myModelEl = $("<div></div>").appendTo($body);
this.myModelView = new MyModelView({
model: window.mymodel,
el: myModelEl
});
}
});
window.MyApp=Backbone.Router.extend({
路线:{
“家”
},
初始化:函数(){
},
主页:函数(){
var$body=$(document.body).empty();
var mymodel=$(“”)。appendTo($body);
this.myModelView=新建myModelView({
型号:window.mymodel,
我的模特儿
});
}
});
现在,您还没有调用render(),但您的视图已按预期成功连接到DOM。您还可以利用Backbone.Model.fetch()返回的延迟对象,如下所示:
window.MyModel = Backbone.Model.extend({
url: '/mymodel'
});
//when the model is fetched, store a reference to the jQuery deferred object
window.MyModelFetch = window.MyModel.fetch();
window.MyModelView = Backbone.View.extend({
template: _.template($('#mymodel-template').html()),
initialize: function () {
_.bindAll(this, 'render');
},
render: function () {
//reference the deferred object and use 'done' method
//to register a callback after complete
window.MyModelFetch.done(function(){
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
}
});
Backbone.DeferrableModel = Backbone.Model.extend({
fetch: function(){
this.fetching = Backbone.Model.prototype.fetch.apply(this, arguments);
return this.fetching;
}
});
您可能希望创建主干模型的扩展,该扩展将延迟对象存储在您可以引用的模型上,如下所示:
window.MyModel = Backbone.Model.extend({
url: '/mymodel'
});
//when the model is fetched, store a reference to the jQuery deferred object
window.MyModelFetch = window.MyModel.fetch();
window.MyModelView = Backbone.View.extend({
template: _.template($('#mymodel-template').html()),
initialize: function () {
_.bindAll(this, 'render');
},
render: function () {
//reference the deferred object and use 'done' method
//to register a callback after complete
window.MyModelFetch.done(function(){
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
}
});
Backbone.DeferrableModel = Backbone.Model.extend({
fetch: function(){
this.fetching = Backbone.Model.prototype.fetch.apply(this, arguments);
return this.fetching;
}
});
然后在视图渲染方法中,可以这样说:
render: function () {
//the deferred reference is now directly referenced from your model
this.model.fetching.done(function(){
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
}
使用扩展模型并在整个主干应用程序中遵循此模式非常方便。True,但随后使用错误数据渲染视图:PSo在这里,您正在initialize和home函数中创建MyModelView的实例?或者我应该将其从初始化中删除?如果正确,请将其从初始化中删除。很抱歉给你带来了困惑。不管怎样,把它放在初始化中并不总是有意义的,因为根据调用的路由方法,通常会呈现不同的视图。我删除了在路由器中呈现的调用,但保留了将视图“el”属性添加到文档中的代码。因此,当获取完成时,它会更改我的模型,从而引发更改事件,调用render方法。。。我花了几个小时才弄明白这就是为什么我的应用程序不能正常工作,有时不能正常工作,或者只能在某些浏览器上工作,而不能在其他浏览器上工作。我想,当你考虑fetch应该如何工作时,这是一个新手的错误。吸取的教训。我认为有太多的主干网示例使用了硬编码数据和非常重要的概念,比如这个被搁置一旁的概念。
render: function () {
//the deferred reference is now directly referenced from your model
this.model.fetching.done(function(){
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
}