javascript 在backbone.js 中使用bind 传递上下文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7254290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:27:52  来源:igfitidea点击:

Passing context with bind in backbone.js

javascriptbackbone.js

提问by nottombrown

I want my panels to re-render themselves when they are clicked.

我希望我的面板在被点击时重新渲染。

However, when I perform a click I get the following:

但是,当我执行单击时,我得到以下信息:

Uncaught TypeError: Cannot call method 'get' of undefined

It appears that the "this" that I'm logging is in fact the model itself:

看来我记录的“这个”实际上是模型本身:

_callbacks: Object
_changed: true
_escapedAttributes: Object
_previousAttributes: Object
attributes: Object
cid: "c0"
collection: r.d
id: "f5589ba4-a0aa-dd86-9697-30e532e0f975"
__proto__: n

I'm having trouble figuring out why the appropriate "this" isn't preserved by passing my context into model.bind.

我无法通过将我的上下文传递到 model.bind 来弄清楚为什么没有保留适当的“this”。

Here's my code:

这是我的代码:

// Models
window.Panel = Backbone.Model.extend({

    defaults: function(){
        return {
            flipped: false,
        };
    },

    toggle: function(){
        this.save({flipped: !this.get("flipped")});
    },

});


// Collections

window.PanelList = Backbone.Collection.extend({

    model:Panel,

    localStorage: new Store("panels"),    

    flipped: function(){
        return this.filter(function(panel){ return panel.get("flipped"); })
    }   
});


// Global collection of Panels
window.Panels = new PanelList;

// Panel View

window.PanelView = Backbone.View.extend({ 

    tagName: 'div',

    template: _.template($("#panel-template").html()),  

    events: {
        "click" : "toggle"
    },

    initialize: function(){
        this.model.bind("change", this.render, this) 
        $(this.el).html(this.template(this.model.toJSON()));
    },     

    render: function(){    
        console.log(this);
        var flipped = this.model.get("flipped")
        if (flipped){
           $(this.el).addClass("flip"); 
        } else{
           $(this.el).removeClass("flip"); 
        }           
        return this   
    },

    toggle: function(){
        this.model.toggle(); 
    }
});   

回答by idbentley

The backbone-y way of doing this is to use the _.bindAll(...)function provided by underscore:

这样做的主干方式是使用_.bindAll(...)下划线提供的功能:

initialize: function(){
    _.bindAll(this, "render");
    this.model.bind("change", this.render) 
    $(this.el).html(this.template(this.model.toJSON()));
}

What _.bindAlldoes is documented here, but it is essentially built exactly for this purpose. If you want to have thisproperly set in allfunctions of the object, you can call _.bindAll(this)with no list of functions. I tend to have this global bind function in most of my views.

这里_.bindAll记录什么,但它本质上正是为此目的而构建的。如果您想在对象的所有功能中this正确设置,您可以在没有功能列表的情况下调用。在我的大多数视图中,我倾向于使用这种全局绑定功能。_.bindAll(this)

回答by rkw

I ran into the same issue and ended up using underscore.js's _.bind() method instead. I queried SO for a response, and it was the reply I got.

我遇到了同样的问题,最终使用 underscore.js 的 _.bind() 方法代替。我向 SO 询问答复,这就是我得到的答复。

Try changing: this.model.bind("change", this.render, this)

尝试改变: this.model.bind("change", this.render, this)

To: this.model.bind("change", _.bind(this.render, this))

到: this.model.bind("change", _.bind(this.render, this))