【问题标题】:Backbone.js: calling render() from view's Initialize: functionBackbone.js:从视图的 Initialize: 函数调用 render()
【发布时间】:2011-09-13 10:42:42
【问题描述】:

我希望我的视图在首次创建时呈现自身,因此我在 initialize: 函数中调用 this.render();,如下所示(删除了一些代码):

var MyView = Backbone.View.extend({

    el: $("#mydiv"),

    initialize: function() {
        this.render();
    }
...

render: 函数中,我将循环遍历一个子集合,并附加每个子元素的渲染视图:

render: function() {
    this.model.somecollection.forEach(function(c) {
        var view = new ChildView({ model: c });
        this.el.append(view.render().el); //*****
    });
    return this;
},

我遇到的问题是渲染函数中对this 的引用(标有星号)设置为window 而不是MyView 对象,这会导致错误。

我假设我调用 render 不正确(当前为 this.render(); )。我应该怎么做才能保留this 上下文?

【问题讨论】:

  • 在 for 循环外将其作为that 安全。
  • @ZeissS-Doh!我很愚蠢 - 添加这个作为答案,我会接受它。

标签: javascript backbone.js


【解决方案1】:

在 for 循环之外保存 this

var that = this;

如果您使用_.each()this 不会在循环内传输。

【讨论】:

  • Backbone.Collection.each() 为上下文接受第三个参数。
  • 科比的评论很重要。 var that=this; 的把戏有点老套,现在感觉有点笨拙。使用更好的each 实现会稍微降低噪音。
  • 您也可以使用 .bind() 来设置 this 上下文。
【解决方案2】:

在 Javascript 中,每当您输入新的函数上下文时,this 的值都可能发生了变化。您只需在输入函数之前存储this 的值即可:

render: function() {
    var self = this;
    this.model.somecollection.forEach(function(c) {
        var view = new ChildView({ model: c });
        self.el.append(view.render().el); //*****
    });
    return this;
},

【讨论】:

    【解决方案3】:

    这就是我们在这里使用它的方式,

    这样在初始化时仍然会调用渲染。

    ContactView = Backbone.View.extend({
        initialize: function(){
            this.render();
        },
        render: function(){
            // we use underscsore templating, this just gives a chunk of html
            var template = _.template( $("#search_template").html(), {} );
            // and we load that template html into the Backbone "el"
            this.el.html( template );
        }
    });
    

    我们在创建视图时将“el”赋予视图, 并且 render 函数将 html 插入到该元素中。

    var contact_view = new ContactView({ el: $("#contact-list") });
    

    【讨论】:

    • 谢谢。事实证明,这对我来说是一个愚蠢的错误(因为 foreach/).each 而失去了这个上下文)。但很高兴看到另一种方法。
    【解决方案4】:

    在匿名函数的上下文中,this 指的是全局范围。如果您希望以您编写的方式使用代码,则需要明确保留它。假设您的页面中有 jquery:可以使用 $.proxy 函数:

    this.model.somecollection.forEach($.proxy(function(c) {
            var view = new ChildView({ model: c });        
            this.el.append(view.render().el);
     },this));
    

    或者,下划线有一个 _.bind 函数,它以类似的方式工作。 此外,如果您定义一个局部变量并将其分配给 this 在匿名函数之外,您可以在匿名函数内部使用它来代替 this。

    【讨论】:

      【解决方案5】:

      如果 somecollection 是 Backbone.Collection 你应该可以说:

      this.model.somecollection.each(..., this);

      最后一个参数是函数内部使用的上下文。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-22
        相关资源
        最近更新 更多