PDA

View Full Version : MVC Application requires for instanceof



OllieJ
7 May 2014, 2:28 AM
Hi,

I have an application in a workspace using a third party ExtJS library which I have created a package for.
Part of the library code checks whether a function argument is an instance of Ext.data.Model, this code is in a subclass of Ext.data.Model itself. This seems to work fine in standalone applications however did not work when used within a package in my workspace. I have managed to get it working by adding requires: ['Ext.data.Model'] to my Application.js but this doesn't seem correct to me.

I have added the framework directive to the package .cfg file, the package relies heavily on ExtJS so it definitely has access to it and builds successfully by itself.
I have checked the order the files are loaded without the requires statement and Model.js is loaded before the problem file.
Please does anyone know what may cause this behaviour?

For clarity example code would be:



Ext.define('MyPackage.A', {
extend: 'Ext.data.Model',
...

});

Ext.define('MyPackage.B', {
extend: 'MyPackage.A',
...

}
});

Ext.define('MyPackage.C', {
extend: 'MyPackage.A',
...
setRelation: function(relationOrId) {
this.set('relationId', (relationOrId instanceof Ext.data.Model) ? relationOrId.getId() || relationOrId.internalId : relationOrId);
}
}
});

Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
...
testSetRelation: function () {
var b = Ext.create('MyPackage.B',{...}),
c = Ext.create('MyPackage.C',{...});
c.setRelation(b);//Fails. sets relationId property to the actual object not the id
}
});



checked in chrome console and
relationOrId instanceof Ext.data.Model == false

skirtle
7 May 2014, 11:57 AM
Bit of a guess but perhaps Ext.data.Model is being loaded twice? By the time of the instanceof check the original definition of Model has been replaced with a new one, so it doesn't count as an instance?

jsakalos
7 May 2014, 12:05 PM
Files are loaded and processed asynchronously so it may seem that Model is loaded (and processed) before the dependent file but it may not be. Putting the required model in Application models:[] is perfectly correct, use it if you need to.

skirtle
7 May 2014, 12:13 PM
I'm not so sure. Doesn't this:


relationOrId instanceof Ext.data.Model == false

imply that Ext.data.Model is loaded? If it weren't then the instanceof check would throw an error instead?

Further, the instanceof check is inside a subclass of Ext.data.Model, so the method can't be called until after Ext.data.Model is loaded.

jsakalos
7 May 2014, 12:17 PM
Sure, Model must be loaded when the above executes. I suppose the OP has an Application with launch method so if he puts the required model to app models:[] then model must be loaded and defined before the launch runs. Of course, there are many ways how something can go awry...

OllieJ
7 May 2014, 11:55 PM
Ideally I wouldn't want to have to specify the requires in the application every time I use that package, I did try putting the requires in the Model subclass within the package but that didn't work. What I can't understand is to create a subclass surely it must load the Model class first... The idea of it being loaded twice is possible...

jsakalos
8 May 2014, 2:21 AM
I don't know how the 3rd party lib is used in your app, how and when it is loaded and when it runs, hence let's do it otherwise.

What you really need is to check if relationOrId is instance of Ext.data.Model, right? For that you can check the isModel property. For example:


if(relationOrId.isModel) {
// some stuff
} else {
// some other stuff
}

OllieJ
8 May 2014, 5:08 AM
I don't know how the 3rd party lib is used in your app, how and when it is loaded and when it runs, hence let's do it otherwise.

What you really need is to check if relationOrId is instance of Ext.data.Model, right? For that you can check the isModel property. For example:


if(relationOrId.isModel) {
// some stuff
} else {
// some other stuff
}


Thanks, ideally I would have liked to find out what causes this behaviour, but this override will do for now. Better than using the ambiguous requires statement I guess.