I am using ClassFactory.mixInInterface to introduce custom initialization code into all Canvases and into DynamicForms.
But SmartClient calls wrong initInterface method for wrong classes. See sample code and explanation below.
Reproducible on SmartClient version 9.0 and 9.0a feature explorer with this sample code.
In the sample above I do this:
1) define interface "CanvasIFace" with custom initInterface method.
2) mix in interface "CanvasIFace" into "Canvas" class and sub classes. So the CanvasIFace.initInterface method is called before init of Canvas and all sub classes.
3) define interface "TestIFace" with custom initInterface method.
4) mix in interface "TestIFace" into "DynamicForm" class and all sub classes. So the TestIFace.initInterface method should be called before init of DynamicForm and all sub classes.
5) I create HLayout instance. It is sub class of Canvas so CanvasIFace.initInterface is called - OK.
bug: HLayout is not a sub class of DynamicForm so TestIFace.initInterface should NOT be called ... but it is called as alert is displayed.
Fix:
The ClassFactory._mixInProperties have to duplicate content of _initInterfaceMethods and _destroyInterfaceMethods, which are inherited from superclass.
isc.addMethods(isc.ClassFactory, {
//...
_mixInProperties : function (source, destination, asClassProperties) {
//... exising code ...
if (propName == this._initInterfaceMethodName && !asClassProperties) {
// patch any initInterface() methods onto a special array on the classObject to
// be called at class creation.
if (destinationClass._initInterfaceMethods == null) {
destinationClass._initInterfaceMethods = []
} else {
destinationClass._initInterfaceMethods = destinationClass._initInterfaceMethods.duplicate();
};
destinationClass._initInterfaceMethods[destinationClass._initInterfaceMethods.length] = propValue;
} else if (propName == this._destroyInterfaceMethodName && !asClassProperties) {
// patch any destroyInterface() methods onto a special array on the classObject to
// be called at class destruction.
if (destinationClass._destroyInterfaceMethods == null) {
destinationClass._destroyInterfaceMethods = [];
} else {
destinationClass._destroyInterfaceMethods = destinationClass._destroyInterfaceMethods.duplicate();
}
destinationClass._destroyInterfaceMethods[destinationClass._destroyInterfaceMethods.length] = propValue;
}
Thank You for fixing the code :-)
But SmartClient calls wrong initInterface method for wrong classes. See sample code and explanation below.
Reproducible on SmartClient version 9.0 and 9.0a feature explorer with this sample code.
Code:
isc.defineInterface("CanvasIFace").addInterfaceProperties({ initInterface : function() { //a method which is called before init of all Canvases //... in my real implementation there is some code of course } }); isc.ClassFactory.mixInInterface("Canvas", "CanvasIFace"); isc.defineInterface("TestIFace").addInterfaceProperties({ initInterface : function() { alert("TestIFace.initInterface called"); } }); isc.ClassFactory.mixInInterface("DynamicForm", "TestIFace"); //The HLayout initialization should call only CanvasIFace.initInterface, but because alert is displayed you can see that it by mistake calls also TestIFace.initInterface isc.HLayout.create();
1) define interface "CanvasIFace" with custom initInterface method.
2) mix in interface "CanvasIFace" into "Canvas" class and sub classes. So the CanvasIFace.initInterface method is called before init of Canvas and all sub classes.
3) define interface "TestIFace" with custom initInterface method.
4) mix in interface "TestIFace" into "DynamicForm" class and all sub classes. So the TestIFace.initInterface method should be called before init of DynamicForm and all sub classes.
5) I create HLayout instance. It is sub class of Canvas so CanvasIFace.initInterface is called - OK.
bug: HLayout is not a sub class of DynamicForm so TestIFace.initInterface should NOT be called ... but it is called as alert is displayed.
Fix:
The ClassFactory._mixInProperties have to duplicate content of _initInterfaceMethods and _destroyInterfaceMethods, which are inherited from superclass.
isc.addMethods(isc.ClassFactory, {
//...
_mixInProperties : function (source, destination, asClassProperties) {
//... exising code ...
if (propName == this._initInterfaceMethodName && !asClassProperties) {
// patch any initInterface() methods onto a special array on the classObject to
// be called at class creation.
if (destinationClass._initInterfaceMethods == null) {
destinationClass._initInterfaceMethods = []
} else {
destinationClass._initInterfaceMethods = destinationClass._initInterfaceMethods.duplicate();
};
destinationClass._initInterfaceMethods[destinationClass._initInterfaceMethods.length] = propValue;
} else if (propName == this._destroyInterfaceMethodName && !asClassProperties) {
// patch any destroyInterface() methods onto a special array on the classObject to
// be called at class destruction.
if (destinationClass._destroyInterfaceMethods == null) {
destinationClass._destroyInterfaceMethods = [];
} else {
destinationClass._destroyInterfaceMethods = destinationClass._destroyInterfaceMethods.duplicate();
}
destinationClass._destroyInterfaceMethods[destinationClass._destroyInterfaceMethods.length] = propValue;
}
Thank You for fixing the code :-)
Comment