2014-07-22 21 views
0

我來自java的背景,而使用Extjs4.2時JavaScript很新。爲什麼函數未定義,即使它使用console.dir在對象中列出?

困擾我很多的是未定義函數或變量錯誤,如下面的示例。

說我用聽衆樹店裏聽樹節點事件像下面擴大:

//define a model 
    Ext.define('Person', { 
     extend: 'Ext.data.Model', 
     fields: [ 
      { name: 'id', type: 'int' }, 
      { name: 'name', type: 'string' } 
     ] 
    }); 
    //create a tree store 
    var store = Ext.create('Ext.data.TreeStore', { 
     model: 'Person', 
     root: { 
      name: 'People', 
      id : -1, 
      expanded: false 
     }, 
     proxy: { 
      type: 'ajax', 
      api: { 
       create: 'createPersons', 
       read: 'readPersons', 
       update: 'updatePersons', 
       destroy: 'destroyPersons' 
      }, 
      reader : { 
       type : "json", 
       root : "children" 
      } 
     }, 
     listeners : { 
      'beforeexpand' : function(node,eOpts){ 
       console.log("requesting child of node "+node.get("id")); 
      }, 
      'expand' : function(node, eOpts) { 
       console.dir(this); 
       //why getById undefined 
       console.info(this.getNodeById("1").get("name")); 
      } 
     } 
    }); 

我的問題是:

由於console.dir(本)印(在擴大回調函數)顯示:

$className 
    "Ext.data.TreeStore" 
alias 
    ["store.tree"] 
getNodeById 
    function(a) 
    $extIsFunction 
     true 
    $isFunction 
     1 
    $name 
     "getNodeById" 
    $owner 
     A() 
    __proto__ 
     function() 
    $extIsFunction 
     true 
    $isFunction 
     1 

我們知道,這裏的'this'是指Ext.data.TreeStore。我擡起頭API文檔,還發現了getNodeById方法,它的聲明是:

getNodeById(id) : Ext.data.NodeInterface 
Returns the record node by id 
Parameters 
    id : Object 
Returns 
    Ext.data.NodeInterface 

但爲什麼我仍然得到錯誤? :

TypeError: this.getNodeById(...) is undefined 

    -->console.info(this.getNodeById("1").get("name")); 
+0

是否有可能'this'被另一個函數改變爲另一個對象?而不是使用'console.dir(this)',看看'console.log(typeof this.getNodeById)'返回 – David

+1

看起來不是函數是未定義的,而是函數的結果。所以會出現錯誤信息,因爲您嘗試在未定義的結果上調用get(「name」)'。 –

+0

@ Chips_100,@David,謝謝你們倆。使用typeof得到一個返回的函數,所以getNodeById實際上是一個樹存儲的方法。在我錯誤的地方,由於json格式,服務器端沒有將節點信息傳遞給客戶端錯誤,所以這個。getNodeById(「1」)確實會得到未定義的節點,然後get(「name」)產生錯誤。看起來錯誤消息在它出現的地方不是很準確。 – wangdq

回答

0

this可以在Javascript相當困難。與其他語言相比,函數的這個關鍵字在JavaScript中的行爲有點不同。在大多數情況下,這個的值由函數的調用方式決定。它不能在執行過程中通過賦值來設置,並且每次調用該函數時都可能會有所不同。

'expand' : function(node, eOpts) { 
     console.dir(this); 
     //why getById undefined 
     console.info(this.getNodeById("1").get("name")); 
    } 

DOCS

果殼

expand(p, eOpts) Fires after this Panel has expanded. 

Available since: 2.3.0 

Parameters p : Ext.panel.Panel The Panel that has been expanded. 
eOpts : Object The options object passed to Ext.util.Observable.addListener. 

在您的代碼是對expand事件的引用。您需要使用p或在您的案件node如上圖所示,而不是

大多數Javascript你會看到類似下面的東西:

function outerFun() { 
    var self = this; 
    console.log(this) 
    function innerFun() { 
     console.log(self) 
     console.log(this) 
    } 
} 

在上面雖然變化兩個功能自我沒有。這是更好的練習,並使代碼更易於維護人員閱讀。

+0

謝謝你的回覆。我找到了錯誤原因。當我聽Tree store擴展事件時,使用this.getNodeById是可以的(儘管使用節點更好)。真正發生這種情況的是服務器端json格式錯誤,那麼樹節點還沒有被初始化,所以this.getNodeById(「1」)得到了一些未定義的東西。該錯誤消息不太準確並且很有幫助。 – wangdq

相關問題