Наличие модели Backbone, разделенной между несколькими видами, является довольно распространенной ситуацией. Тем не менее, скажем, эта модель - UserModel
. Он обрабатывает несколько методов, позволяя пользователю зарегистрироваться или войти, например.Одна модель Backbone для нескольких видов, которая обрабатывает выборку()?
И когда пользователь регистрируется, вызывается функция fetch для получения данных пользователя. Поэтому модель не может получить this.fetch()
в своем методе initialize
.
Куда изволите его? Как?
Это наш простой 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-запрос.
В принципе, модель могла бы забрать istself после успешного вызова своего метода login
, но пользователь может прийти на страницу или перезагрузить свой браузер, уже входящий в систему. Кроме того, пользователь может приземлиться на любую страницу, нет никакого способа скажем, он собирается HomeView
до CartView
.
Есть два варианта, которые я вижу. Либо 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
документ ссылка & Подчеркивание-х _.isEmpty
's.
В каком месте находится чище? Есть ли другой подход, который я мог пропустить?
+1 для бесконечного цикла, очевидно, что я не тестировал его: p Имея пользовательскую базовую модель, звучит здорово! Почему использование 'UserModel' переопределяет' customFetch'? Он может быть объявлен непосредственно в базовом классе. Затем я бы назвал 'customFetch' в представлениях, где я просто хочу убедиться, что модель заполнена или непосредственно' fetch', когда мне нужно иметь дело с самыми современными данными. – Buzut
@Buzut снова снова мое личное предпочтение. Давайте установим, что у нас был «TimeModel», который также расширяет «MyModel», эту модель мы хотели бы «получать» каждый раз. Я бы предпочел писать 'customFetch' везде в моем коде, а не смешивать' customFetch' и 'fetch'. Вы легко можете установить 'customFetch' в' MyModel' как свой собственный код. Итак, опять же, именно так оно и имеет смысл для меня, надеюсь, мои рассуждения имеют смысл. В конечном счете это то, что лучше всего подходит для вас, но старайтесь соответствовать вашему подходу. –
Спасибо за то, что поняли, и за то, что нашли время, чтобы предложить исчерпывающий ответ. – Buzut