将 EXTJS 4.1 升级到 4.2... _incr_ 在 Ext.util.Observable 中未定义

Posted

技术标签:

【中文标题】将 EXTJS 4.1 升级到 4.2... _incr_ 在 Ext.util.Observable 中未定义【英文标题】:Upgrading EXTJS 4.1 to 4.2... _incr_ is undefined in Ext.util.Observable 【发布时间】:2014-04-29 22:16:39 【问题描述】:

我遇到了一个问题,从 EXTJS 4.1 升级到 4.2 后,我收到错误:“未捕获的 TypeError:未定义不是函数”,它指向 Ext.utilObservable 的 ext-all.js addListener 方法.具体来说,当调用_incr_函数时,增加监听器的数量:

  addListener: function(ename, fn, scope, options) 
        var me = this,
            config, event,
            prevListenerCount = 0;


        if (typeof ename !== 'string') 
            options = ename;
            for (ename in options) 
                if (options.hasOwnProperty(ename)) 
                    config = options[ename];
                    if (!me.eventOptionsRe.test(ename)) 

                        me.addListener(ename, config.fn || config, config.scope || options.scope, config.fn ? config : options);
                    
                
            
            if (options && options.destroyable) 
                return new ListenerRemover(me, options);
            
        

        else 
            ename = ename.toLowerCase();
            event = me.events[ename];
            if (event && event.isEvent) 
                prevListenerCount = event.listeners.length;
             else 
                me.events[ename] = event = new ExtEvent(me, ename);
            


            if (typeof fn === 'string') 
                scope = scope || me;
                fn = Ext.resolveMethod(fn, scope);
            
            event.addListener(fn, scope, options);



            if (event.listeners.length !== prevListenerCount) 
                me.hasListeners._incr_(ename);                   // <----- right here
            
            if (options && options.destroyable) 
                return new ListenerRemover(me, ename, fn, scope, options);
            
        
    ,

我尝试用 EXTJS 4.1 中的方法替换它,但我发现更多错误。是否可能是 EXTJS 配置不正确或缺少文件?

编辑有问题的部分:

    Ext.Loader.setConfig(
enabled: true
);
Ext.Loader.setPath('Ext.ux', '/_layouts/1033/scripts/perf/extjs/ux');

Ext.require([
        'Ext.ux.grid.Printer',
    //    'Ext.grid.plugin.BufferedRenderer'
 //  'Ext.ux.grid.plugin.BufferedRenderer'
 //       'Ext.ux.exporter.Exporter'
  ]);



Ext.onReady(function () 

Ext.QuickTips.init();
var myMask = new Ext.LoadMask('CostSummaryGrid',  msg: "Loading..." );
//debugger;

Ext.define('CostSummaryGrid', 
    extend: 'Ext.data.Model',
    fields: [
        name: 'WBSId',
        type: 'int'
    , 
        name: 'WBSName',
        type: 'string'
    , 
        name: 'EndDate',
        type: 'string',
        convert: function (value, record) 
            if (value == null)
                return null;
            //debugger;
            date = Ext.Date.parse(value, 'MS', true);
            UTCdate = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
            return Ext.Date.format(UTCdate, appConfig.DateFormat);
        
    , 
        name: 'PlannedValue',
        type: 'float'
    , 
        name: 'EarnedValue',
        type: 'float'
    , 
        name: 'ActualCost',
        type: 'float'
    , 
        name: 'ScheduleVariance',
        type: 'float'
    , 
        name: 'CostVariance',
        type: 'float'
    , 
        name: 'CurrentBudget',
        type: 'float'
    , 
        name: 'EstimateAtCompletion',
        type: 'float'
    , 
        name: 'VarianceAtCompletion',
        type: 'float'
    , 
        name: 'SPI',
        type: 'float'
    , 
        name: 'CPI',
        type: 'float'
    ]
);


var costSummaryStore = Ext.create("Ext.data.Store", 
    model: 'CostSummaryGrid',
    autoLoad: false,
    pageSize: 100,
    proxy: 
        type: 'ajax',
        url: siteUrl + '_vti_bin/performanceportaldata.svc/GetCostSummaryGridFiltered',
        noCache: false,
        //extraParams: wbsFilter: '',
        sortParam: undefined,
        limitParam: undefined,
        startParam: undefined,
        pageParam: undefined,
        headers: 
            'Accept': 'application/json'
        ,
        reader: 
            type: 'json',
            root: 'd'
        
    ,
    storeId: 'CostSummaryStore',
    wbsFilterable: true,
    filterable: true,
    startDateFilterable: false,
    costSetFilterable: true,
    wbsCostFilterable: true,
    listeners: 
        beforeload: function () 
            myMask.show();
        ,
        load: function () 
            myMask.hide();
           // grid.addDocked( xtype: 'exporterbutton' , 'top');
        ,
    ,
    LoadIfReady: function() 
        if (this.filterableReady === true && this.costSetFilterableReady === true
                && this.wbsCostFilterableReady === true && this.wbsFilterableReady === true) 
            debugger;
            this.load();
            return true;
              
    
);

var grid = Ext.create('Ext.grid.Panel', 
    store: costSummaryStore,
    autoLoad: true,
    plugins: 
          ptype: 'bufferedrenderer',
          trailingBufferZone: 50,  // Keep 20 rows rendered in the table behind scroll
          leadingBufferZone: 100   // Keep 50 rows rendered in the table ahead of scroll
    ,
    features: [
        ftype: 'fixedsummary'
    ],
    tbar: [
        text: 'Print',
        iconCls: 'icon-print',
        handler : function()
            Ext.ux.grid.Printer.printAutomatically = false;
            Ext.ux.grid.Printer.print(grid);
            
     //john wilson was here
    ],
    showSummaryRow: false,
    columns: [
        text: 'WBS Name',
        flex: 3,
        align: 'left',
        sortable: true,
        dataIndex: 'WBSName',
        fixedSummaryType: 'count',
        fixedSummaryRenderer: function (value, metadata, record) 
            //return Ext.String.format('<em>Totals:</em>', value);
            return value;
        
    , 
        text: 'Planned Value',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'PlannedValue',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals
    , 
        text: 'Earned Value',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'EarnedValue',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: 'Actual Cost',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'ActualCost',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: '<html>Schedule <br>Variance</html>',
        flex: 2,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'ScheduleVariance',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: 'Cost Variance',
        flex: 2,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'CostVariance',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: '<html>Budget at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'CurrentBudget',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: '<html>Estimate at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'EstimateAtCompletion',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: '<html>Variance at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'VarianceAtCompletion',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    , 
        text: 'SPI',
        flex: 1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.renderKPI,
        dataIndex: 'SPI',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: function (val, meta, record, ri, ci, s, v) 
            if (typeof (record) === 'undefined') 
                return null;
            
            var earnedValue = 0, planned = 0;
            for (var i = 0; i < record.fields.length; i++) 
                var fieldName = record.fields.items[i].name;
                if (fieldName.lastIndexOf("EarnedValue", 0) === 0) 
                    earnedValue = record.get(fieldName);
                
                if (fieldName.lastIndexOf("PlannedValue", 0) === 0) 
                    planned = record.get(fieldName);
                
            
            var retVal = earnedValue / planned;

            if (planned === 0)  retVal = 0; 

            if (KPIStore.getById('SPI') != null) 
                return PerfPortal.Format.renderKPIDirect(retVal, meta, 'SPI');
            
            else
                return retVal;
        

    , 
        text: 'CPI',
        flex: 1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.renderKPI,
        dataIndex: 'CPI',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: function (val, meta, record, ri, ci, s, v) 
            if (typeof (record) === 'undefined') 
                return null;
            
            var earnedValue = 0, actual = 0;
            for (var i = 0; i < record.fields.length; i++) 
                var fieldName = record.fields.items[i].name;
                if (fieldName.lastIndexOf("ActualCost", 0) === 0) 
                    actual = record.get(fieldName);
                
                if (fieldName.lastIndexOf("EarnedValue", 0) === 0) 
                    earnedValue = record.get(fieldName);
                
            
            var retVal = earnedValue / actual;
            if (actual === 0)  retVal = 0; 
            if (KPIStore.getById('CPI') != null) 
                return PerfPortal.Format.renderKPIDirect(retVal, meta, 'CPI');
            
            else
                return retVal;
            //return Ext.util.Format.number(record.get('EarnedValue')/record.get('PlannedValue'),'0.00');
        

    ],
    height: 520,
    width: 1000,
    title: 'Cost Summary',
    renderTo: 'CostSummaryGrid',
    viewConfig: 
        stripeRows: true,
        loadMask: false
    

);

var summary = Ext.create('Ext.toolbar.Toolbar', 
    dock: 'bottom',
    //height: 25,
    items: [ xtype: 'displayfield']
);

var toolBar = Ext.create('Ext.toolbar.Toolbar', 
    dock: 'bottom',
    //height: 25,
    items: [ xtype: 'tbfill']
);
//var exportButton = Ext.create


grid.addDocked(toolBar);
var KPIStore = Ext.getStore('KPIStore');

if (KPIStore.isLoading()) 

    KPIStore.on('load', function (store, records, options) 
        addLegend(store, toolBar, 'CPI');
        toolBar.insert('-');
        addLegend(store, toolBar, 'SPI');
    );

else 
    addLegend(KPIStore, toolBar, 'CPI');
    toolBar.insert('-');
    addLegend(KPIStore, toolBar, 'SPI');


function addLegend(store, toolBar, type) 

    var KPIdef = store.getById(type);

    var poor = '<span style="margin-right: 5px; background-color: ' + KPIdef.data.Poor_color + '; color: ' + KPIdef.data.Poor_color + ';">__</span>' + KPIdef.data.Poor_label;
    var caution = '<span style="margin-right: 5px; margin-left: 10px; background-color: ' + KPIdef.data.Caution_color + '; color: ' + KPIdef.data.Caution_color + ';">__</span>' + KPIdef.data.Caution_label;
    var good = '<span style="margin-right: 5px; margin-left: 10px; background-color: ' + KPIdef.data.Good_color + '; color: ' + KPIdef.data.Good_color + ';">__</span>' + KPIdef.data.Good_label;

    toolBar.insert( xtype: 'tbtext',
        padding: '5, 5, 5, 5',
        text: KPIdef.data.Title + ': ' + poor + caution + good
    
               );

);

【问题讨论】:

更有可能是您的页面中混合了一些不能很好地配合使用的包含。尝试从一些非常简单的东西重新开始,然后将您的代码添加到其中。 发布导致问题的组件配置。几乎可以肯定问题出在应用程序空间而不是在库中。 最可能的原因是你有一些没有调用可观察构造函数的类。 大家好,我已经用有问题的代码更新了问题。如果您有任何其他见解,我很乐意听到。 【参考方案1】:

使用 ExtJs 4.2,如果一个类定义了事件,它必须扩展 Ext.util.Observable 或添加 Ext.util.Observable 的 mixin。 Observable 的构造函数也必须在这个类的构造函数中调用,如下 sn-p,

Ext.define('Employee', 
        // Change 1.....
        extend: 'Ext.util.Observable',
        constructor: function(config)

            this.addEvents(
                "sayHello" : true,
                "sayGoodbye" : true
            );
            // Change 2.....
            this.callParent(arguments)
        
    );

Ext.define('Employee', 
        extend: 'Some other class',

        // Change 1
        mixins: 
            observable: 'Ext.util.Observable'
        ,

        constructor: function(config)

            this.addEvents(
                "sayHello" : true,
                "sayGoodbye" : true
            );
            // Change 2.....
            this.mixins.observable.constructor.call(this);
        
    );

【讨论】:

以上是关于将 EXTJS 4.1 升级到 4.2... _incr_ 在 Ext.util.Observable 中未定义的主要内容,如果未能解决你的问题,请参考以下文章

从 Sencha ExtJS 4.0 迁移到 ExtJS 4.1

Extjs 4.1 - 如何将数据从商店加载到另一个商店

Extjs 4.1 - 如何将侦听器从对象 A 复制到对象 B

如何将这个小代码从 Extjs3 升级到 Extjs4.2?

将自定义 JSON 解析为 ExtJS 4.1 TreeStore

如何将 ExtJS 3.2 迁移/升级到 ExtJS 4.2 下载以及如何下载迁移的文件?