backbone.js视图在模型获取之前呈现
我正在尝试制作一个小型的backbone.js应用程序,但它与事物的顺序发生冲突。
在我的html文件中,头中有两个脚本块:
<script type="text/template" id="model-template">
<a href="#"><%= title %></a>
</script>
<script type="text/javascript">
jQuery(function(){
window.model.fetch();
});
</script>
在我的app.js中,我定义了一个简单的模型,视图和路由器。
(function($) {
window.MyModel = Backbone.Model.extend({
url: '/mymodel'
});
window.mymodel = new MyModel();
$(document).ready(function() {
window.MyModelView = Backbone.View.extend({
template: _.template($('#mymodel-template').html()),
initialize: function () {
_.bindAll(this, 'render');
},
render: function () {
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
});
window.MyApp = Backbone.Router.extend({
routes: {
'': 'home'
},
initialize: function () {
this.myModelView = new MyModelView({
model: window.mymodel
});
},
home: function() {
var $body = $('body');
$body.empty();
$body.append(this.myModelView.render().el);
}
});
$(function() {
window.App = new MyApp();
Backbone.history.start({pushState: true});
});
})(jQuery);
该应用程序由一个简单的sinatra应用程序提供服务。 url /mymodel
提供一个静态json文件:
{
"title": "My Model",
}
加载应用程序时,我在javascript控制台中出现错误:
Uncaught ReferenceError: title is not defined
问题似乎是,在从服务器获取模型之前,视图呈现自己。 这是为什么?
昨天,我跟踪了PeepCode的前两个backbone.js截屏视频。 我试图将我的应用程序与屏幕录像中的应用程序进行比较,但无法看到为什么我的应用程序想要工作的原因。
有什么建议么?
在这种情况下,您应该引导您的模型数据,以便在页面加载时可用。
代替
window.model.fetch();
把这样的东西(如果使用.erb)
<script>
window.model = new MyModel(<%= @model.to_json %>);
</script>
否则,您需要在获取模型后渲染视图,例如
绑定视图以在模型更改时进行渲染
initialize: function () {
_.bindAll(this, 'render');
this.model.on("change", this.render);
},
或者处理model.fetch的成功并呈现视图
window.model.fetch({
success: function (model, response) {
window.MyApp.myModelView.render();
}
});
您还可以利用Backbone.Model.fetch()
返回的延迟对象http://api.jquery.com/category/deferred-object/,如下所示:
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;
}
}
使用扩展模型并在整个骨干应用程序中遵循此模式可能非常方便。
从服务器重置模型的状态。 如果模型从未填充过数据,或者如果您想确保您拥有最新的服务器状态,那么这很有用。 如果服务器的状态与当前属性不同,将会触发“更改”事件。 接受选项散列中的成功和错误回调,它们作为参数传递(模型,响应)。
在这种情况下,您需要在成功回调中呈现视图。
model.fetch({
error: function () {
},
success: function (model, response) { // model is ready now
// do view stuff here
}
});
链接地址: http://www.djcxy.com/p/66831.html