Это моя первая попытка использования Backbone.js, поэтому я решил создать простое тестовое приложение, которое имитирует меню ресторана с элементами меню.Я следил вместе с этим классным постом в блоге от andyet.net .
У меня возникла проблема при добавлении модели в коллекцию.Я связал метод представления с событием добавления коллекции, которое должно обновить представление.Ниже приведен код, в котором удалено как можно больше ненужного кода.
(примечание: для краткости я удалил такие вещи, как объявления и замыкания локальной области действия var
.и я знаю, что это раздражает, но это должно быть довольно просто и легко понять):
MenuItem = Backbone.Model.extend({
// initialize functions removed for brevity
});
Menu = Backbone.Model.extend({
// initialize functions removed for brevity
// MenuSelection property is defined here.
});
MenuSelection = Backbone.Collection.extend({ model: MenuItem });
MenuItemView = Backbone.View.extend({
// render template
});
/**
* This is unaltered from the code. The error occurs here.
*/
RestaurantAppView = Backbone.View.extend({
addMenuItem : function (MenuItem) {
var view = new MenuItemView({ model : MenuItem });
this.menuList.append(view.render().el);
// ERROR occurs here. error: "this.menuList is undefined"
},
initialize : function () {
this.model.MenuSelection.bind('add', this.addMenuItem);
},
render : function () {
$(this.el).html(ich.app(this.model.toJSON()));
this.menuList = this.$('#menuList'); // IT IS DEFINED HERE
return this;
}
});
/**
* Everything after this I left in just-in-case you need to see it.
*/
RestaurantAppController = {
init : function (spec) {
this.config = { connect : true };
_.extend(this.config, spec);
this.model = new Menu({
name : this.config.name,
});
this.view = new RestaurantAppView({ model : this.model });
return this;
}
};
$(function() {
// simulating ajax JSON response.
var json = {
Menu : {
name : 'Appetizers',
MenuItem : [
{
name : 'toast',
description : 'very taosty',
price : '$20.00'
},
{
name : 'jam',
description : 'very jammy',
price : '$10.00'
},
{
name : 'butter',
description : 'very buttery',
price : '$26.00'
}
]
}
};
window.app = RestaurantAppController.init({
name : json.Menu.name
});
$('body').append(app.view.render().el);
app.model.MenuSelection.add(json.Menu.MenuItem);
});
Я отметил с комментариями проблемную область.В соответствии с базовой документацией :
Если на странице включен jQuery или Zepto, каждое представление имеет функцию $, которая выполняет запросы, находящиеся в пределах области действия элемента представления.
Итак, если я устанавливаю this.menuList = this.$('#menuList');
в методе рендеринга, почему я не могу получить доступ к this.menuList
в методе addMenuItem
?Демо, на которое я ссылаюсь сверху, делает это точно так.Также, если я поменяю this.menuList
на селектор jQuery, вот так:
addMenuItem : function (MenuItem) {
var view = new MenuItemView({ model : MenuItem });
$('#menuList').append(view.render().el);
}
Все работает нормально.Но я не хочу, чтобы перевыбирал идентификатор menulist каждый раз, когда addMenuItem
выполняется.RightWay TM должен кешировать его после его рендеринга.
Также обратите внимание: я подумал, что, возможно, проблема в том, что шаблон ICanHaz не возвращается достаточно быстро, но тогда this.menuList
будетпустой массив, а не undefined
, так что это не так.