在backbone.js中添加事件会丢失此上下文

时间:2014-10-01 14:10:58

标签: javascript jquery backbone.js

我有一个骨干应用程序,在函数中插入模板,在另一个函数中,将部分模板插入到该模板中。问题是事件在第一个模板中绑定得很好而在第二个模板中没有绑定。通常,我会添加这样的事件:

events:{
    'click .buttonOne': 'eventOne',  //works
    'click .buttonTwo': 'eventTwo'  //doesnt work

},

但是,部分模板按钮不会绑定(不会触发任何事件)。我不确定这个的原因。因此,为了克服这个问题,我在插入部分时添加事件,如下所示:

        $("#eventTwo").click(function(){
            alert('test')
        });

但是,即使我添加

,我也无法获得“this”对象
  var that = this

事件绑定之前。我绑定不正确吗?还是有一种方法我应该得到“这个”,我不是在做什么?

由于

编辑:无效工作的完整代码示例

我的代码是这样的:当用户点击图像时,会触发一个事件(这是一个添加到正文的模板。原始视图中的事件(即他们点击的图像)工作正常但模板添加,事件不会。这是我的代码:

模板功能

template:function (renderOptions) {
//various case statements to determine which template to use
//returns the name of the template to use
return 'activityImages';
}

上面的模板有视图的html代码。最后,我有这个:

<div id ="imageViewerDiv" class = "imageViewerDiv"></div>

然后我在templateContext函数中添加模型:

templateContext:function (renderOptions) {
 // builds out a list of objects and returns it to be used in the template

}

图像代码点击事件:

  viewImage: function(e){
    try{
        var template = window.app.getTemplate('activityImageViewer')
        var that = this;           
        //other variables defined here

        //I am trying to create an effect that pops up a modal div, with the image in it
        //in order for me to cover the entire app, i have to append this div to the body
        $(document).find('body').append($("#imageViewerDiv"))
        var temp = template({
            //variables I need passed here
        });

        this.addImageToViewer(temp);
    }catch(e){
        throw e;
    }
},

//here I add a partial template to the main template.  this is where events fail to bind.
//in my template i have this, within a div, inside a table 

<div id = "prevImgGalleryImg" name = "prevImgGalleryImg" style="float: right; padding-left: 10px; cursor: pointer;">Prev</div>

addImageToViewer: function(template){
    try{
        var that = this;
        var temp = template;
        $(document).find('body').append($("#imageViewerDiv"))
        $("#imageViewerDiv").append(template);

        //I add events here, as they do not bind any other way          

        $("#prevImgGalleryImg").click(function(){
           //cant get this or that here
            alert('test')
        });

    }catch(e){
        throw e;
    }

},

要添加事件,我这样做,但它不起作用:

events:{
  //my events
    'click .prevImgGalleryImg': 'prevImgGalleryImg'

},

prevImgGalleryImg: function(e){
  alert('test');
},

解决方案:

经过一番挣扎,我想通了。当我添加div时,像这样:

 $(document).find('body').append($("#imageViewerDiv"))

我应该像这样添加它:

  this.$el.append($("#imageViewerDiv"))

2 个答案:

答案 0 :(得分:0)

你的主干应该是这样的:

events:{
    'click .buttonOne': 'eventOne',  //works
    'click .buttonTwo': 'eventTwo'  //doesnt work

},

eventOne: function () {
    console.log(this);
},

eventTwo: function () {
    console.log(this);
}

现在您可以正确访问它了。不知道为什么我们使用jquery来附加事件。

希望这有帮助。

答案 1 :(得分:0)

请参阅_.bind_.bindAll

从您的视图的构造函数/初始化函数中调用_.bind / _.bindAll将强制执行正确的this上下文:

var MyCustomView = Backbone.View.extend({
    ...,
    events: {
        'click .buttonOne': 'eventOne',
        'click .buttonTwo': 'eventTwo'
    },
    initialize: function( options ) {
        ...;

        _.bindAll(this, 'eventOne', 'eventTwo');
    }
    ...,
    eventOne: function( event ) {
        // 'this' will always reference MyCustomView
    },
    eventTwo: function( event ) {
        // 'this' will always reference MyCustomView
    }
});