-
21 Jul 2008 2:51 PM #1
Ext 2.0 and Prototype 1.6.0.2 - conflicting Function.prototype.defer methods
Ext 2.0 and Prototype 1.6.0.2 - conflicting Function.prototype.defer methods
This problem was previously reported here, and a potential solution was posted on an external blog here. I have come up with an alternate solution to the problem and thought I would post it here in case it is of use to anyone else.
Code:/* There is a pretty nasty conflict issue between Ext and Prototype with the Function.prototype.defer method. Prototype implements the method and relies on its behavior for certain things (such as asynchronous AJAX requests). Ext implements the method with different behavior and relies on it pretty heavily, as well. Due to the order of our includes (Prototype, then Ext), Ext's defer method "wins" and is used even when Prototype is trying to use its own defer method. This can cause some strange AJAX issues with onSuccess handlers being invoked before the AJAX request has successfully been completed. In order to solve, we are going to override defer with our own custom implementation. This implementation is going to have to know about the "special" ways that Ext and Prototype invoke this method and invoke the proper method depending on which one was intended. Luckily, Prototype only ever calls this method with either no arguments or with a single argument value of the number 1. Thus, in those two cases, we will invoke Prototype's defer method. In all other cases, we will invoke Ext's implementation. Note that Prototype's defer method is actually just a chained call to delay.curry(0.01) (per prototype.js - 1.6.0.2). Note that we need to keep a reference to the Ext defer method prior to overwriting the method. */ Function.prototype.oldExtDefer = Function.prototype.defer; Function.prototype.defer = function() { if(arguments.length==0 || (arguments.length==1 && arguments[0]==1)) { return this.delay.curry(0.01).apply(this, arguments); } return this.oldExtDefer.apply(this, arguments); };
-
5 Nov 2009 9:21 AM #2
Clarification on how to implement your solution
Clarification on how to implement your solution
Thanks lenzb for your valuable input.
For solving my issue I added the suggested lines by lenzb (in bold font) in the prototype.js file like this:
/* From lenzb */
Function.prototype.oldExtDefer = Function.prototype.defer;
/* From Prototype */
Object.extend(Function.prototype, {
argumentNames: function() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
},
bind: function() {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
},
bindAsEventListener: function() {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
return __method.apply(object, [event || window.event].concat(args));
}
},
curry: function() {
if (!arguments.length) return this;
var __method = this, args = $A(arguments);
return function() {
return __method.apply(this, args.concat($A(arguments)));
}
},
delay: function() {
var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
},
defer: function() {
var args = [0.01].concat($A(arguments));
return this.delay.apply(this, args);
},
wrap: function(wrapper) {
var __method = this;
return function() {
return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
}
},
methodize: function() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
return __method.apply(null, [this].concat($A(arguments)));
};
}
});
/* From lenzb */
Function.prototype.defer = function() {
if(arguments.length==0 || (arguments.length==1 && arguments[0]==1)) {
return this.delay.curry(0.01).apply(this, arguments);
}
return this.oldExtDefer.apply(this, arguments);
};
I am using Prototype 1.6.0.3 and Ext 3.0 for your reference and consider as well the order of the js files:
1. ext-base.js
2. ext-all.js or ext-all-debug.js
3. prototype.js
-
11 Jan 2012 6:48 AM #3
thank you, it helped me out of trouble
thank you, it helped me out of trouble
I'm using prototype 1.6.0.3 and extjs 3.4.1


Reply With Quote