在幾個視圖之間共享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