ExtJS:范围混乱

时间:2013-09-13 18:35:49

标签: javascript extjs scope extjs4

来自C ++背景,我在Javascript / ExtJS函数范围内有点迷失 - 特别是在处理事件时。

假设我有一个监听许多不同事件的控制器。这些事件可能来自托管视图,商店,应用程序级别等。目前,我正在做这样的事情以确保正确的范围界定:

init: function() {
    me.control({
        'someSelector': {
            someEvent: me.onSomeEvent.bind(me)
        },
        ...
    });
    me.application.on({
        applicationEvent: me.onApplicationEvent.bind(me)
    });
},
onSomeEvent: function() {...},
onApplicationEvent: function() {...},

这是正确的做事方式吗?我害怕在thisonSomeEvent()内使用onApplicationEvent,除非我特别知道this指向的内容。想法?

编辑:这里有一些示例代码,用于显示this可能误导的位置。

init: function() {
    this.control({
        'uploadform *': {
            formUpload: this.onFormUpload
        }
    });
},

onFormUpload: function(form) {
    if(form.isValid()) {
        var formData = form.getValues();
        Ext.Ajax.request({
            url: 'upload',
            method: 'POST',
            jsonData: {
                form: formData
            },
            success: this.onFormUploadSuccess // here, this is the controller
        });
    }
},

onFormUploadSuccess: function() {
    ...                                       // here, this isn't the controller
    this.application.fireEvent('dealAdded');  // this.application === undefined!!
}

1 个答案:

答案 0 :(得分:3)

尽管在JS中确定范围可能会让人感到困惑,但不要害怕它。 您的控制器维护范围,因此您无需验证代码。它应该是这样的:

Ext.define('Pandora.controller.Station', {
    extend: 'Ext.app.Controller',
    ...    
    init: function() {
        this.control({
            'stationslist': {
                selectionchange: this.onStationSelect
            },
            ...
        });
    },    
    ...    
    onStationSelect: function(selModel, selection) {
        this.application.fireEvent('stationstart', selection[0]);
    },    
   ...
});

优秀的活动处理帖子在这里:Explain ExtJS 4 event handling。 此外,当某些东西看起来不对时我求助于console.log(this)只是为了确保我正在查看正确的范围。

修改 在看到您提供的示例后,问题不在于控制器本身,而是在Ajax请求中是异步并且默认情况下在Window作用域中执行。 ExtJS允许您在请求中使用scope:this config设置范围,这将设置控制器作为成功回调的范围。

Ext.Ajax.request({
            url: 'upload',
            method: 'POST',
            jsonData: {
                form: formData
            },
            success: this.onFormUploadSuccess // here, this is the controller
     ,scope:this
        });