0
votes

I come from java background,and quite new to javascript while using Extjs4.2 .

What troubled me a lot is ,undefined function or variable error,like the example following.

Say I use listeners in tree store to listen tree node expand event like below :

//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"));
            }
        }
    });

My problem is :

Since console.dir(this) print (in expand callback function) show :

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

we know ,here 'this' refer to Ext.data.TreeStore . And I looked up the API doc ,also found the getNodeById method,its declaration is :

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

But why I still get the error ? :

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

  -->console.info(this.getNodeById("1").get("name"));
1
Is it possible that this is being changed by another function to a different object? Instead of using console.dir(this), see what console.log(typeof this.getNodeById) returnsDavid
It looks like not the function is undefined, but the result of the function. So the error message occurs, because you try to call get("name") on an undefined result.Dennis
@ Chips_100,@ David,thank you both.Using typeof get a function returned,so getNodeById is really a method of tree store.Where I was wrong was ,server side haven't pass the node info to the client due to json format error,so this.getNodeById("1") really get undefined node,then get("name") incur error .It seemed error message is not quite accurate at the point where it occurs.wangdq

1 Answers

0
votes

this can be rather difficult in Javascript. A function's this keyword behaves a little differently in JavaScript compared to other languages. In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called.

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

DOCS

Nutshell

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.

In your code this is a reference to the expand event. You need to use p or in your case node as shown above instead of this

Most Javascript you will see something similar to the below:

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

In the above although this changes in the two functions self does not. It is better practice and makes the code more readable to a maintainer.