我试图将用户定义的回调绑定为Backbone的click事件。



var View = Backbone.View.extend({

    events: {
      'click': 'testClick'
    },

    tagName: "li",

    attributes: {
      class: "item"
    },

    initialize: function() {

        this.render();

    },

    testClick: function(){

    },

    render: function() {

      $("#container").append(this.$el.html("Click Me!!"));

    }

  });

function Item() {

  var _view = View.extend({

    testClick: this.testClick.bind(this)

  });

  this.view = new _view();

}

Item.prototype = {

  testClick: function() {

    alert("testClick from prototype called!");

  }

};


var myItem = new Item();

myItem.testClick = function() {
  alert("testClick from instance called!");
}

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

</head>
<body>
  <div id="container"></div>
</body>
</html>





点击“点击我”,它会警告“来自原型的testClick!”

我不确定为什么没有调用实例的警报。我在这里做错了什么?请帮忙!

最佳答案

因为下面这行:

testClick: this.testClick.bind(this)


分离testClick实例的Item函数成员。您实际上是在重用一个函数,并且这两种方法之间没有链接。

考虑以下示例:

var obj = {
   foo: function() {
      console.log('I was foo!');
   }
}

var detachedFoo = obj.foo;
obj.foo = function() {
   console.log('The new foo!');
}

obj.foo === detachedFoo // false
obj.foo() // logs 'The new foo!'
deatchedFoo(); // logs 'I was foo!'


如果使用以下语法,则alert将显示“来自实例的testClick!”。

testClick: () => {
   this.testClick();
}


这是因为上面的代码调用了Item实例的当前.testClick方法。

09-27 16:41