0

我有一个可变计时。

var timeKeep;

我这样定义它:

timeKeep = Class.create({
  initialize: function() {
    this.initObservers();
  },

  initObservers: function() {
    $$('input').each( function(el) {
      el.observe('keypress', function(ev) {
        // the key code for 'enter/return' is 13
        if(ev.keyCode === 13){
          timeKeep.submit();
              // Uncaught TypeError: Object function klass() {
              // this.initialize.apply(this, arguments);
              // } has no method 'submit'
        }
      });
    });
  },

  submit: function() {
    alert('Submitted!');
  }
})

我得到的错误在它发生的行下方被注释掉。我认为这与在不同范围内调用 timeKeep 方法有关吗?

在 foreach 语句中调用 timeKeep.method() 是否有问题?

4

3 回答 3

1

问题在于你的 OOP 风格。使用闭包,以便调用类的当前实例。

  initObservers: function () {
      var that = this;
      $$('input')
          .each(function (el) {
              el.observe('keypress', function (ev) {
                  // the key code for 'enter/return' is 13
                  if (ev.keyCode === 13) {
                      that.submit();
                  }
              });
          });
  },

你也可以看看绑定

  initObservers: function() {
      var submit = this.submit.bind(this);
      $$('input')
          .each(function (el) {
              el.observe('keypress', function (ev) {
                  // the key code for 'enter/return' is 13
                  if (ev.keyCode === 13) {
                      submit();
                  }
              });
          });
  },
于 2013-06-12T13:40:33.833 回答
1

您假设Class.create返回您正在定义的类型的对象的实例,但不,它返回一个构造函数,用于创建您正在定义的类的实例。

您可以将新关键字添加到作业中,然后您将及时保留您想要的内容:

timeKeep = new Class.create({
...
})()
于 2013-06-12T14:05:11.677 回答
0

正如所建议的 - usingFunction#bind()将解决您的问题,但有一种更清洁的方法,以便您可以继续this在类范围内使用。

还要研究该invoke()方法,因为这是使用它的绝佳机会。$$()返回一个元素列表,如果您想对所有元素执行相同的功能,invoke()则将处理对列表的迭代。

timeKeep = Class.create({
  initialize: function() {
    this.initObservers();
  },

  initObservers: function() {
    $$('input').invoke('observe','keypress',function(ev) {
      // the key code for 'enter/return' is 13
      if(ev.keyCode === 13){
        timeKeep.submit();
        // Uncaught TypeError: Object function klass() {
        // this.initialize.apply(this, arguments);
        // } has no method 'submit'
      }
//Add the bind method to the closure to bind 'this' inside that function scope
//to 'this' of the class
//the binding will allow you to call this.submit() instead of timeKeep.submit
//as well as access any of the class properties and methods inside this closure
    }.bind(this));
  } ,

  submit: function() {
    alert('Submitted!');
  }
});

关于观察者的 PrototypeJS 文档http://api.prototypejs.org/dom/Event/observe/ - 查看标题Using an Instance Method as a Handler

于 2013-06-12T14:39:39.290 回答