2011-12-15 25 views
1

我試圖使用Mootools動態地向頁面添加一個按鈕。這一切工作正常,除了addButton功能中的addEvent。我得到一個錯誤,說「對象的屬性'sayHi'javascript:void(0);不是一個函數」。MooTools綁定/保持類方法和內部函數的作用域

我認爲這是由於我的範圍,我以某種方式必須將addButton函數綁定回全局「this」?有人能解釋我做錯了什麼嗎?謝謝!

var myClass = new Class({ 
    initialize: function(){ 
     this.sayHi(); 
    }, 

    sayHi: function(){ 
     alert('Hello World!'); 
    }, 

    addButton: function(){ 
     this.hiButton = new Element('a', { 
      id: 'sayhi', 
      html: 'Hi!', 
      href: 'javascript:void(0);', 
      events: { 
       click: function(){ 
        this.sayHi(); 
       } 
      } 
     }).inject($('myDiv')); 
    } 
});  

回答

2

的問題是,在點擊處理程序,該this值不再是原來的對象,而是被點擊的按鈕。

有可能是解決這個問題的具體MooTools的路,但在功能包裝此對象的創建將是解決這個問題的簡單,原始的方式:

function getMyClass(){ 
    var self = new Class({ 
     initialize: function(){ 
      this.sayHi(); 
     }, 

     sayHi: function(){ 
      alert('Hello World!'); 
     }, 

     addButton: function(){ 
      this.hiButton = new Element('a', { 
       id: 'sayhi', 
       html: 'Hi!', 
       href: 'javascript:void(0);', 
       events: { 
        click: function(){ 
         self.sayHi(); 
        } 
       } 
      }).inject($('myDiv')); 
     } 
    }); 

    return self; 
}  

然後

var myClass = getMyClass(); 

編輯

雖然上述是JavaScript中一個相當標準的習慣用法,但我被告知它不能很好地與MooTools搭配使用。如果是這樣的話,我會去與此(作爲另一個答案已經提到):

var myClass = new Class({ 
    initialize: function(){ 
     this.sayHi(); 
    }, 

    sayHi: function(){ 
     alert('Hello World!'); 
    }, 

    addButton: function(){ 
     var self; 
     this.hiButton = new Element('a', { 
      id: 'sayhi', 
      html: 'Hi!', 
      href: 'javascript:void(0);', 
      events: { 
       click: function(){ 
        self.sayHi(); 
       } 
      } 
     }).inject($('myDiv')); 
    } 
});  
+0

感謝您的快速答覆! – julio 2011-12-15 18:16:19

+0

@julio - 我的榮幸 – 2011-12-15 18:16:57

2

你得到這個問題,因爲當click處理程序執行this是代表anchor元素對象,而不是你的myClass

更改addButton到:

addButton: function(){ 
    var that = this; 
    this.hiButton = new Element('a', { 
     id: 'sayhi', 
     html: 'Hi!', 
     href: 'javascript:void(0);', 
     events: { 
      click: function(){ 
       that.sayHi(); 
      } 
     } 
    }).inject($('myDiv')); 
} 

HERE是正在運行的例子。切換到代碼視圖以查看源代碼。

1

處理這種推薦的方法,在很多mootools的多個插件如下:

var myClass = new Class({ 
    initialize: function(){ 
     this.sayHi(); 
    }, 

    sayHi: function(){ 
     alert('Hello World!'); 
    }, 

    addButton: function(){ 
     var self = this; 
     this.hiButton = new Element('a', { 
      id: 'sayhi', 
      html: 'Hi!', 
      href: 'javascript:void(0);', 
      events: { 
       click: function(){ 
        self.sayHi(); 
       } 
      } 
     }).inject($('myDiv')); 
    } 
}); 

你可以看到它是非常相似,亞當Rackis解決方案,但你並不需要一個包裝類函數調用。

恕我直言,它保持代碼更清潔/保養/ mooish!

希望這會有所幫助。

1

Omg,綁定怎麼辦?做var self = this;是錯的。你可以做這樣的事情:

var myClass = new Class({ 
initialize: function(){ 
    this.sayHi(); 
}, 

sayHi: function(){ 
    alert('Hello World!'); 
}, 

addButton: function(){ 
    this.hiButton = new Element('a', { 
     id: 'sayhi', 
     html: 'Hi!', 
     href: '#', 
     events: { 
      click: function(){ 
       this.sayHi(); 

       // this will stop event propagation 
       return false; 
      }.bind(this) 
     } 
    }).inject($('myDiv')); 
} 
}); 

你可以檢查一下here