在几个视图之间共享Backbone模型是一种相当普遍的情况。尽管如此,假设这个模型是UserModel
。它处理几种方法,允许用户注册或登录。几个视图的一个主干模型,谁处理fetch()?
而且当用户登录时,调用fetch来获取用户的数据。因此,该模型无法使用initialize
方法中的this.fetch()
自取。
它应该从哪里取?怎么样?
这是我们简单UserModel
:
const UserModel = Backbone.Model.extend({
// get url for 'me' (ie connected user)
url() {
return app.endpoint + '/users/me/' + app.conToken;
},
login(email, password, rememberMe, callback) {
…
},
signup(email, password, firstname, lastname, callback) {
…
}
});
现在让我们假设它是由两个共享:
HomeView
& CartView
app.HomeView = Backbone.View.extend({
template: app.tpl.home,
initialize() {
// model is passed @ instanciation
this.model.fetch();
this.listenTo(this.model, 'sync', this.render);
},
render() {
…
}
});
app.CartView = Backbone.View.extend({
template: app.tpl.cart,
initialize() {
// model is passed @ instanciation
this.model.fetch();
this.listenTo(this.model, 'sync', this.render);
},
render() {
…
}
});
现在,如果我实例化HomeView
,userModel
将是牵强。但是如果在稍后的时间点,我会立即使用CartView
,这个模型会再次被提取。这使得一个无用的http请求。
基本上,模型可以在成功调用其login
方法后自动获取,但用户可以到达页面或重新加载已登录的浏览器。此外,用户可以登陆任何页面,但无法说他要在CartView
之前去HomeView
。
我看到两个选项。无论是UserModel
巧妙地处理多个fetch
调用,像这样:
const UserModel = Backbone.Model.extend({
// get url for 'me' (ie connected user)
url() {
return app.endpoint + '/users/me/' + app.conToken;
},
isSync() {
// an hour ago
let hourAgo = Date.now() - 3600000;
// data has been fetched less than an hour ago
if (this.fetchTime && hourAgo > this.fetchTime) return true;
return false;
},
fetch() {
// has not already fetched data or data is older than an hour
if (!this.isSync()) {
this.fetchTime = Date.now();
this.fetch();
return;
}
// trigger sync without issuing any http call
this.trigger('sync');
},
…
});
这样的话,我能叫this.model.fetch()
多次需要,是在视图中无状态的。
或者,我可以处理一个视图层上:
app.HomeView = Backbone.View.extend({
template: app.tpl.home,
initialize() {
// model is passed @ instanciation
// fetch model if empty
if (_.isEmpty(this.model.changed)) this.fetch();
// render directly if already populated
else this.render();
// render on model sync
this.listenTo(this.model, 'sync', this.render);
},
render() {
…
}
});
如果需要的话,Backbone's model.changed
DOC参考&下划线的_.isEmpty
's。
哪种方式更清洁?有没有其他方法可能会错过?
对于无限循环+1,很明显我没有测试过它:p有一个定制的基础模型听起来很棒!为什么'UserModel'重写'customFetch'虽然?它可以直接声明为基类。然后,我会在视图中调用'customFetch',在那里我只是想确保模型已经填充或直接'获取',当我需要处理最新的数据。 – Buzut
@Buzut再次以我的个人喜好再次。让我们设置一个'TimeModel',它也扩展了'MyModel',这个模型我们每次都想''获取''。我宁愿在我的代码中编写'customFetch',而不是混合'customFetch'和'fetch'。你可以很容易地在'MyModel'中设置'customFetch'作为你的自定义代码。所以再次,只是这对我来说是有意义的,希望我的推理很有意义。最终它会为你写得最好,但要尽量与你的方法保持一致。 –
感谢您提出明确的建议,并花时间提出全面的解答。 – Buzut