javascript - Backbone.js |如何存储 View 元素以供以后检索?

原文 标签 javascript jquery view undefined backbone.js

这是我第一次尝试使用 Backbone.js,所以我决定制作一个简单的测试应用程序来模拟带有菜单项的餐厅菜单。我跟着 this cool blog post from andyet.net .

将模型添加到集合时遇到问题。我已将 View 方法绑定(bind)到应该更新 View 的集合的添加事件。这是尽可能多地删除不相关代码的代码。

(注意:为简洁起见,我删除了局部范围 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);
});  

我已经用评论标记了有问题的区域。根据Backbone Documentation :

If jQuery or Zepto is included on the page, each view has a $ function that runs queries scoped within the view's element.



所以,如果我设置 this.menuList = this.$('#menuList');在render方法中,为什么无法访问this.menuListaddMenuItem方法?我在顶部链接到的演示就是这样。另外,如果我换出 this.menuList对于 jQuery 选择器,如下所示:
addMenuItem : function (MenuItem) {
    var view = new MenuItemView({ model : MenuItem });
    $('#menuList').append(view.render().el);
}

一切正常。但我没有想要每次重新选择菜单列表 ID addMenuItem被执行。 RightWayTM 是在渲染后缓存它。

另请注意:我认为问题可能在于 ICanHaz 模板返回的速度不够快,但后来 this.menuList将是一个空数组,而不是 undefined ,所以不是这样。

最佳答案

你遇到了 JavaScript 的第一个问题——动态范围的 this关键词。当你起飞时this.addMenuItem作为引用而不绑定(bind)它,addMenuItem函数失去了 this 的概念.有两种简单的方法可以在您的代码中修复它,或者替换此行:

this.model.MenuSelection.bind('add', this.addMenuItem);

有了这个:
this.model.MenuSelection.bind('add', _.bind(this.addMenuItem, this));

或者将此行添加到您的初始化函数的顶部,这将有效地完成相同的事情:
_.bindAll(this, 'addMenuItem');

关于javascript - Backbone.js |如何存储 View 元素以供以后检索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4542433/

相关文章:

javascript - 从 child 到 parent 的 react 钩子(Hook)回调

jquery - addClass if else 不能正常工作

php - 通过AJAX发送特殊字符(“&lt”,“&gt”,“&amp”)

MYSQL View ?连接两个表

javascript - knockout validation 并显示工具提示

javascript - 如何在 reactJS 中处于 "update"状态?

javascript - 检查文本字段中的值是否已更改并发布。 JS。滑轨

javascript - 带有标签栏的温泉滑动菜单不起作用

mysql - 是否可以仅在数据发生更改时更新 mysql View ?

postgresql - 将 View 加入另一个表