Ste*_*hen 3 javascript jquery view undefined backbone.js
这是我第一次尝试使用Backbone.js,所以我决定制作一个简单的测试应用程序来模拟带有菜单项的餐馆菜单.我跟随来自andyet.net的这篇很酷的博客文章.
将模型添加到集合时遇到问题.我已经将一个视图方法绑定到应该更新视图的集合的add事件.这是代码,尽可能多地删除不相关的代码.
(注意: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);
});
Run Code Online (Sandbox Code Playgroud)
我已经在评论中标出了有问题的区域.根据Backbone文档:
如果页面中包含jQuery或Zepto,则每个视图都有一个$函数,该函数运行在视图元素中作用域的查询.
那么,如果我this.menuList = this.$('#menuList');在render方法中设置,为什么我不能this.menuList在addMenuItem方法中访问?我在顶部链接的演示就像这样.另外,如果我换掉this.menuListjQuery选择器,就像这样:
addMenuItem : function (MenuItem) {
var view = new MenuItemView({ model : MenuItem });
$('#menuList').append(view.render().el);
}
Run Code Online (Sandbox Code Playgroud)
一切正常.但我不希望重新选择的菜单列表ID每次addMenuItem执行.RightWay TM将在渲染后对其进行缓存.
另请注意:我认为问题可能是ICanHaz模板没有足够快地返回,但是后来this.menuList将是一个空数组,不是undefined,所以不是这样.
你正在使用JavaScript(动态范围的this关键字)进入#1陷阱.当你this.addMenuItem作为参考而没有绑定它时,该addMenuItem函数失去了它的概念this.有两种简单的方法可以在代码中修复它,或者替换这一行:
this.model.MenuSelection.bind('add', this.addMenuItem);
Run Code Online (Sandbox Code Playgroud)
有了这个:
this.model.MenuSelection.bind('add', _.bind(this.addMenuItem, this));
Run Code Online (Sandbox Code Playgroud)
或者将此行添加到初始化函数的顶部,这将有效地完成同样的事情:
_.bindAll(this, 'addMenuItem');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2204 次 |
| 最近记录: |