【问题标题】:How to use scope in nested functions in ExtJS如何在 ExtJS 的嵌套函数中使用作用域
【发布时间】:2012-11-20 08:32:36
【问题描述】:

在嵌套函数中使用 scope 时遇到问题。我的代码在下面,代码中也说明了错误。如何将scope 传递给嵌套函数?

this.store_1.load({
    params  :{start:0, limit:20},
    callback: function(records, operation, success)
    {
        this.store_2.load({
            params      : {argID: argID},
            callback    : function(records, operation, success) {

                var my_data = this.store_2.data.items[0].data;  

                this.my_rowExpander = new Ext.ux.grid.RowExpander({
                    tpl : new Ext.Template(template_str)
                });

                this.MyDetailGraph = this.getMyGraph(graphDataArr);

                this.MyDetailSummaryPanel = new Ext.Panel({ 
                        html    : this.getMyDetailSummary_Template(arg1, arg2, arg3),
                        title   : 'Title'
                });

                this.myPagingBBar = new Ext.PagingToolbar({
                      pageSize      : 20,
                      buttonAlign   : 'center',
                      store         : this.store_1,
                      doRefresh     : function(){
                            this.store.load({ // if I use this.store_1.load gives error this.store_1 is undefined
                                params  :{start:0, limit:20},
                                callback: function(records, operation, success)
                                {   
                                    // here gives error -->  this.updateDetailGraphValue is not a function
                                    this.updateDetailGraphValue(arg1, this.MyDetailGraph, arg2);
                                    // here must be an error like above
                                    this.updateDetailSummaryPanelValue(this.MyDetailSummaryPanel, arg1, arg2, arg3);
                                }
                            });
                      }
                });

                this.MyDetailGrid = new Ext.grid.GridPanel({
                    store       : this.store_1,
                    bbar        : this.myPagingBBar,
                    plugins     : this.my_rowExpander,
                    columns     :[
                                    this.my_rowExpander,
                                    {header: 'header1'},
                                    {header: 'header2'},
                                    {header: 'header3'},
                                    {header: 'header4'}
                                 ]
                });

                argPanel.items.insert(0, this.MyDetailGraph);

                argPanel.items.insert(1, this.MyDetailSummaryPanel);

                argPanel.items.insert(2, this.MyDetailGrid);

                argPanel.doLayout();
            },
            scope       : this
        });
    }, 
    scope : this
});

this.updateDetailGraphValue = function(argMainPanel, argGraph, argDataArray)
{
        this.graph = this.getDetailGraph(argDataArray);
        argMainPanel.remove(argGraph, true);
        argMainPanel.items.insert(0, this.graph);
        argMainPanel.doLayout();
};

this.updateDetailSummaryPanelValue = function(argPanel, arg1, arg2, arg3)
{
        argPanel.update(this.getDetailSummary_Template(arg1, arg2, arg3));
        argPanel.doLayout();
};

【问题讨论】:

    标签: extjs scope nested-function


    【解决方案1】:

    试试下面的代码。但我不知道它会起作用。您尚未在回调中定义 any 最后一次回调的范围 并且您一直在使用 this。最终遇到范围问题只是时间问题。考虑将this 映射到像me 这样的局部变量。

    this.store_1.load({
        params  :{start:0, limit:20},
        scope: this,
        callback: function(records, operation, success)
        {
            this.store_2.load({
                params      : {argID: argID},
                scope: this,
                callback    : function(records, operation, success) {
    
                    var my_data = this.store_2.data.items[0].data;  
    
                    this.my_rowExpander = new Ext.ux.grid.RowExpander({
                        tpl : new Ext.Template(template_str)
                    });
    
                    this.MyDetailGraph = this.getMyGraph(graphDataArr);
    
                    this.MyDetailSummaryPanel = new Ext.Panel({ 
                            html    : this.getMyDetailSummary_Template(arg1, arg2, arg3),
                            title   : 'Title'
                    });
    
                    function innerCB(records, operation, success) {   
                        // here gives error -->  this.updateDetailGraphValue is not a function
                        this.updateDetailGraphValue(arg1, this.MyDetailGraph, arg2);
                        // here must be an error like above
                        this.updateDetailSummaryPanelValue(this.MyDetailSummaryPanel, arg1, arg2, arg3);
                    }
    
                    this.myPagingBBar = new Ext.PagingToolbar({
                          pageSize      : 20,
                          buttonAlign   : 'center',
                          store         : this.store_1,
                          doRefresh     : function(){
                                this.store.load({ // if I use this.store_1.load gives error this.store_1 is undefined
                                    params  :{start:0, limit:20},
                                    scope: this,
                                    callback: innerCB
                                });
                          }
                    });
    
                    this.MyDetailGrid = new Ext.grid.GridPanel({
                        store       : this.store_1,
                        bbar        : this.myPagingBBar,
                        plugins     : this.my_rowExpander,
                        columns     :[
                                        this.my_rowExpander,
                                        {header: 'header1'},
                                        {header: 'header2'},
                                        {header: 'header3'},
                                        {header: 'header4'}
                                     ]
                    });
    
                    argPanel.items.insert(0, this.MyDetailGraph);
    
                    argPanel.items.insert(1, this.MyDetailSummaryPanel);
    
                    argPanel.items.insert(2, this.MyDetailGrid);
    
                    argPanel.doLayout();
                }
            });
        }
    });
    
    this.updateDetailGraphValue = function(argMainPanel, argGraph, argDataArray)
    {
            this.graph = this.getDetailGraph(argDataArray);
            argMainPanel.remove(argGraph, true);
            argMainPanel.items.insert(0, this.graph);
            argMainPanel.doLayout();
    };
    
    this.updateDetailSummaryPanelValue = function(argPanel, arg1, arg2, arg3)
    {
            argPanel.update(this.getDetailSummary_Template(arg1, arg2, arg3));
            argPanel.doLayout();
    };
    

    【讨论】:

    • 我按照你的说法试过了,这里还是报错:this.updateDetailGraphValue(arg1, this.MyDetailGraph, arg2);
    • @vtokmak 我进行了编辑。通常这会起作用,但由于它被放置在已经嵌套的回调中,它也可能会失败。但我认为值得一试。
    • 我仍然无法访问 function innerCB 中的 this.updateDetailGraphValue 函数。我得到同样的错误。很难给函数一个范围:/
    • @vtokmak 我建议您以小步骤重新启动。使用 console.log 检查每个函数中的每个范围。这应该可以帮助您指出您松开它的位置。当您嵌套那么深时,您应该使用映射范围而不是 this。这保留了大多数问题。基本上不可能一直用这个。
    • @vtokmak 就像我说的 :) 但它不是一个全局范围,只是一个映射范围。最常见的是var me = this; 这就是我的意思考虑将它映射到像我这样的局部变量。
    【解决方案2】:

    我在第一次加载时使用了this,我定义了一个全局范围myGlobalScope,然后我在其他地方使用了myGlobalScope

    this.store_1.load({
        params  :{start:0, limit:20},
        scope: this,
        callback: function(records, operation, success)
        {
    
        var myGlobalScope = this; // I have defined this global scope
    
    
            this.store_2.load({
                params      : {argID: argID},
                scope   : myGlobalScope, // use myGlobalScope instead of this
                callback    : function(records, operation, success) {
    
                    var my_data = this.store_2.data.items[0].data;  
    
                    this.my_rowExpander = new Ext.ux.grid.RowExpander({
                        tpl : new Ext.Template(template_str)
                    });
    
                    this.MyDetailGraph = this.getMyGraph(graphDataArr);
    
                    this.MyDetailSummaryPanel = new Ext.Panel({ 
                            html    : myGlobalScope.getMyDetailSummary_Template(arg1, arg2, arg3), // use myGlobalScope instead of this
                            title   : 'Title'
                    });
    
                    this.myPagingBBar = new Ext.PagingToolbar({
                          pageSize      : 20,
                          buttonAlign   : 'center',
                          store         : this.store_1,
                          doRefresh     : function(){
                                this.store.load({ // if I use this.store_1.load gives error this.store_1 is undefined
                                    params  :{start:0, limit:20},
                                    scope   : this,
                                    callback:  function innerCB(records, operation, success) {   
                        myGlobalScope.updateDetailGraphValue(arg1, this.MyDetailGraph, arg2); // use myGlobalScope instead of this
                            myGlobalScope.updateDetailSummaryPanelValue(this.MyDetailSummaryPanel, arg1, arg2, arg3); // use myGlobalScope instead of this
                    }
                                });
                          }
                    });
    
                    this.MyDetailGrid = new Ext.grid.GridPanel({
                        store       : this.store_1,
                        bbar        : this.myPagingBBar,
                        plugins     : this.my_rowExpander,
                        columns     :[
                                        this.my_rowExpander,
                                        {header: 'header1'},
                                        {header: 'header2'},
                                        {header: 'header3'},
                                        {header: 'header4'}
                                     ]
                    });
    
                    argPanel.items.insert(0, this.MyDetailGraph);
    
                    argPanel.items.insert(1, this.MyDetailSummaryPanel);
    
                    argPanel.items.insert(2, this.MyDetailGrid);
    
                    argPanel.doLayout();
                }
            });
        }
    });
    
    this.updateDetailGraphValue = function(argMainPanel, argGraph, argDataArray)
    {
            this.graph = this.getDetailGraph(argDataArray);
            argMainPanel.remove(argGraph, true);
            argMainPanel.items.insert(0, this.graph);
            argMainPanel.doLayout();
    };
    
    this.updateDetailSummaryPanelValue = function(argPanel, arg1, arg2, arg3)
    {
            argPanel.update(this.getDetailSummary_Template(arg1, arg2, arg3));
            argPanel.doLayout();
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-25
      • 2013-07-07
      • 2022-11-27
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2014-07-11
      相关资源
      最近更新 更多