我遇到一个问题,从EXTJS 4.1升级到4.2后,我收到错误:“未捕获TypeError:undefined不是函数”,它指向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
}
);
}
});
答案 0 :(得分:1)
使用ExtJs 4.2,如果一个类上定义了事件,它必须扩展Ext.util.Observable或添加Ext.util.Observable的mixin。还必须在此类的构造函数中调用Observable的构造函数,如下面的代码片段,
Ext.define('Employee', {
// Change 1.....
extend: 'Ext.util.Observable',
constructor: function(config){
this.addEvents({
"sayHello" : true,
"sayGoodbye" : true
});
// Change 2.....
this.callParent(arguments)
}
});
OR
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);
}
});