PDA

View Full Version : Plugins and xtype's for the Ext.data package



eccehomo
26 Dec 2008, 1:13 AM
Hi there.

I have been wondering if there is someone who successfully implemented writing a plugin for a store(or did it ever occur to someone)?

The importance of which is discussed here (the fourth post to be precise):
http://extjs.com/forum/showthread.php?t=55966

Also, if xtype's are possible for the Ext.data package. The power of xtype's, aside from lazy instantiation, really is that a widget could be built based from a json definition and that definition can be loaded asynchronously (e.g, through ajax), and thus, lesser code on the client, and more control (server wise).

If that is possible for the Ext.data package then much better. Suppose this is possible,
All you need to do is to:


CustomerStore = Ext.extend(Ext.data.Store, {
... <extend methods and properties which are impossible to define at the server >
});
Ext.reg('customerstore', CustomerStore);

...then in your grid

customerGrid = new Ext.grid.GridPanel({
store : {xtype : 'customerstore', ... <other definition of store fetched remotely>}
});


Of course, the grid's definition is to be loaded/provided remotely.

The xtype thing is just an idea, it might be a useless feature.

But the plugin feature is definitely a must to me. (That is if something like that isn't included in the coming 3.0 release).

Animal
26 Dec 2008, 1:30 AM
What's the point?

You are going to be creating a Store, what's the problem with putting "new Ext.data.Store(" in there before the "{" character?

mjlecomte
26 Dec 2008, 2:29 AM
I think it was a mistake to split your original thread, as I replied there already.

For something like you're saying here to work, you'd need to do something like an "otype" and have Observable implement it anyway? I noted the problems with that in the other thread, so if that were the case and you just wanted something on store, then maybe you'd do an "stype" if for whatever reason you can't do new yourCustomStore() as Animal is suggesting.

As far as configuring your grid through json (ie. metaData), you can specify metaData as described at top of http://extjs.com/deploy/dev/docs/?class=Ext.data.JsonReader. So you could listen for metachange either in your grid or store and then monitor if an "stype" existed perhaps, or check the store property if there's a "new" there an do an eval on it's value if so.

eccehomo
26 Dec 2008, 11:47 AM
What's the point?

You are going to be creating a Store, what's the problem with putting "new Ext.data.Store(" in there before the "{" character?


Animal, with all due respect, I did not(perhaps from my lack of knowledge and experience on Ext) made any sense from you on this point. Perhaps it would be helpful to make your remarks clear.


I think it was a mistake to split your original thread, as I replied there already.

I started a new thread on the hope of inviting more helpful remarks. I'm afraid yours didn't, as it turned out that I was repeatedly explaining my point.



For something like you're saying here to work, you'd need to do something like an "otype" and have Observable implement it anyway?

Why implement another "type" ("otype") when we have the powerful "xtype"? If I'd go that way, I'd just be adding something to learn about, which does not make sense anyway because its basically the same thing: A COMPONENT TYPE (non-visual/widget at that).



I noted the problems with that in the other thread, so if that were the case and you just wanted something on store, then maybe you'd do an "stype"

Why the implement more "types"? Again, "types" per se are, as far as Ext is concerned, to me, is fully encapsulated with "xtypes".



if for whatever reason you can't do new yourCustomStore() as Animal is suggesting.

I can not make sense out of this.



As far as configuring your grid through json (ie. metaData), you can specify metaData as described at top of http://extjs.com/deploy/dev/docs/?class=Ext.data.JsonReader.


Sure. I could configure a grid from json (thanks to the RemoteComponent plugin) But could I configure that with the store defined on the server? I do not know. That is the point of this thread.


So you could listen for metachange either in your grid or store and then monitor if an "stype" existed perhaps, or check the store property if there's a "new" there an do an eval on it's value if so.

Why all these? If I could provide the definition of store, right from the server, why listen for the metachange event?

eccehomo
26 Dec 2008, 11:56 AM
Perhaps I have not clearly stated myself.

I am asking if the following make sense:
1.) the ability to write plugins (or inject plugins) to the Ext.data package
2.) the ability for xtypes for the descendant classes of store.


Why all these?
1.) Multiple inheritance. Sure, we can achieve multiple inheritance in Javascript. But why all go through that when we can do so with plugins? To me, if Multiple Inheritance isn't possible, then composition is the way to go. With the added methods in the Function prototype added by Ext, that would be relatively trivial.

2.) Stores, as it turned out, are simply components. What is the difference between a Model (the store) and its Representation (e.g, the Grid) ? Nothing. They need each other. So why not provide a "type" for both?. If I can configure a Grid from json (served remotely) based from the powerful "xtypes" why not for Store?

Again, for the interested readers, please refer to the posted link above for a more detailed discussion of the problem domain.

p.s., To Animal and djlecomte, I appreciate the interest, but at this point my mistakes (as you see it) are not made clear to me. Thanks for all your support in the community.

mjlecomte
26 Dec 2008, 4:44 PM
remoteComponent plugin is for Components.

Store is not a Component. It descends from Observable. xtypes are registered with the ComponentMgr....Component Manager. There are ptypes (for plugins) coming with Ext 3.

The Component Class utilizes template method pattern. So certain methods are called at certain points of time. Components get rendered (onRender, afterRender, etc.). Doesn't make sense for something not a descendant of Component.


Stores, as it turned out, are simply components. What is the difference between a Model (the store) and its Representation (e.g, the Grid) ? Nothing. They need each other
Disagree. Have you heard of MVC pattern? Classes are created for a particular interface. Stores can be used for more than just grids for example.

As far as metaData/metaChange... maybe you should read over the autoGrid thread, not just the first post. If you just want to configure a grid from the server, then that does it pretty well.

eccehomo
26 Dec 2008, 7:57 PM
remoteComponent plugin is for Components.

Store is not a Component. It descends from Observable.

That is, again, precisely the issue at hand. I felt that if Store descends from a class which has the capacity to initialise plugins (based on a template method), then it so follows that one can write plugins for store.



xtypes are registered with the ComponentMgr....Component Manager.

Why emphasise the obvious? How could one miss it? But the discussion I want to invoke is that that a Store is a Component is of course not basing from the current codebase as it is; because if so, then there is no discussion; I would be simply repeating what is found in the manual. I want to abuse the idea that both Component and Store descend from an abstract class and that abstract class is the one responsible to initialise plugins.



The Component Class utilizes template method pattern. So certain methods are called at certain points of time. Components get rendered (onRender, afterRender, etc.). Doesn't make sense for something not a descendant of Component.

Why so? Why does it not make sense for classes not descending Component? Do you mean to imply that one cannot achieve the template method pattern in the Ext.data Package by properly applying/extending the classes in the said Package? If that is so, then I dismiss that as absurd.



Disagree. Have you heard of MVC pattern?

Why is the MVC pattern invoked here?


Classes are created for a particular interface.

Do you mean "Widgets (which are classes - classes which extends the dom) are created for a particular interface"? Then I do agree.


Stores can be used for more than just grids for example.

Again, I did not claim otherwise; so why state this?
I simply stated that a Representation (a Grid, Tree, DataView) and a Model (the Store, Record) are the same in the sense that they are to be used, and thus "Components". However, the current abstraction/inheritance model in 2.x does not think so, and thus the problem of not being able to write plugins against the Representation (the Ext.data Package).

I will give an argument why I think store are just "components":
Let component be a class which needs another classes(es) for it to work (in a system).
DOes anyone here used a grid (a representation) WITHOUT a Model (a store)? No.
Does anyone here used a store (a model) WITHOUT a Representation (a grid, a panel, a Form)? No.
What is the difference, in this sense, between them? None. They complement each other: if they do not complement, they are not the same; how could they complement each other if they have different intents? And for that reason, I see them as basically similar (thus giving the name of "Components" to them), because they agree to form part to a certain whole, or effect: data is displayed to the user visually as in a typical grid. They have similar intent.



As far as metaData/metaChange... maybe you should read over the autoGrid thread, not just the first post. If you just want to configure a grid from the server, then that does it pretty well.

Why is that brought up? I am not even asking assistance for the grid, and yet this is invoked. The autogrid can configure a grid, but ONLY THE COLUMNS. What is sought is that a grid store's can be derived from a server. Of course, one could send a definition like this:


//a grid definition from server
{
title : 'test'
.
.
.
store : 'new Ext.data.Store({...})' //"declare" it on the server, then eval on client.
}

and when that definition arrives on the client, eval the store property. But to me that method is not clean enough since I had to write a declaration (and not a definition) of the grid's store on the server. What I seek is that it is possible to define a store from a server through the use of 'xtypes' (a definition).



There are ptypes (for plugins) coming with Ext 3.

Why should that be? I mean, xtypes are sufficient.

Consider this reasoning:

No two or more Classes (be widgets or data-related) released in Ext are the same; i.e., each are unique. (because if the opposite is true, then Ext is a flawed framework; why have two similar classes?). (1)

Because of this uniqueness, an 'xtype' is possible; (i.e, I can associate or provide a "short identifier" to a class. If the classes are not unique, how sure am I that if I gave, ClassX an type "x" it could refer to ClassX alone? Never. To be sure, the present method of declaring xtypes, prevents this confusion: Ext.reg('type', CLASS); prevents classes from having a same type.) (2)

If the widgets Package are classes and the Ext.data package are classes, and all classes are unique, then there is no duplicated class on both package; then there is no intersection in the two sets of classes. Makes sense right? (3)

Classes in the Widgets package are unique; thus we have an 'xtype' for them; Classes in Ext.data Package are unique; thus we can have an 'xtype' for them too.

To be short:
C -> the set of all classes for the Ext.Component family
D -> the set of all classes for the Ext.data familty
C <intersection symbol> D ->Empty Set (The intersection of C and D is empty).

Why is the intersection empty? Because I claimed that no classes are duplicated in Ext (and the community) - whether plugins, extensions, or those released OOB.
If all are unique, then, assigning an xtype to each and every class is just sensible, as we are assigning it currently on the Ext.Component package (which is a set of unique classes).

Does that make sense? Please, someone, show me the fallacy of this reasoning.
Of course I am not suggesting to put an xtype on ALL CLASSES on Ext (TaskMgr, Observable, DomHelper). No, I am simply
stating the fact that one field to denote the uniqueness of the set of all existing and future classes released by Ext and the Community, in this case the 'xtype', is enough.


As for the 'ptypes':

If plugins are classes, and are to be extensions on Ext, then it implies that there occurs no duplication of plugins (ideally). Such that if user A and user B wrote plugins which are completely equal (same name and methods), they must at least be differentiated by a certain mechanism. To me xtype/Ext.reg is that mechanism, and of course, namespacing: and it surely suffices. If it works for Ext as a whole why should it be different for extensions written on Ext?

And besides, some people here are writing plugins and issuing 'Ext.reg' at the end of the plugin's definition, and thus uses xtypes at the end of the plugin's definition. IMHO, adding a 'ptype' is just another thing to acquaint ourselves with without any added benefit (correct me at this point).

If we provide a relational model for all classes in Ext and its extensions, we can have this:



xtype | Class
grid Ext.grid.GridPanel
form Ext.form.FormPanel
...etc ...etc
uxgrid1 Ext.grid.ux.UxGrid1


In this case we have two candidate keys. Of course, we could dispense with either, but the importance of the xtype "field", is the ability to map a given string to a class definition. So why ask for another "type" (e.g, "ptype", "stype"), wherein one should theoretically suffice?


I know that the Ext Team wishes to give the world a mature framework; I hope I am not interpreted as criticising or debasing Ext and its community; my intent is to giveback to the community as much as possible.

eccehomo
26 Dec 2008, 9:33 PM
To make things visual.

This is the current iheritance/abstraction model for the classes of Ext.

For the widgets (or visual/boxed components):


Ext.util.observable
- Ext.Component -->it is in this class which plugins are initialised. with the help of ComponentMgr, this class creates components based on an a definition (xtype)
- Ext.BoxComponent
- etc, etc, (e.g, gridpanel, panel, tabpanel, treepanel)

It is because of this inheritance model, that we are given the capacity to write plugins for any class descending from component.

On the other hand, this is the case for Store and its subclasses:


Ext.util.observable
Ext.data.store -->it is in this class which I feel is ideal to initialise plugins on store (or any of its descendants)
- GroupingStore
- JsonStore
- and all its sublcasses

But to me, this might make sense:


Ext.util.Observable
Ext.XComponent -->now, this class handles the plugins for any component; or if possible, this could handle xtypes for store(s), with the help of ComponentMgr (i.e, ComponentMgr, might need to be overridden)
-Ext.Component
- etc, etc.
-Ext.data.Store
- etc, etc.


Again you might ask: why write plugins for store?

Imagine this situation:

I use a grid, and a standard Store. I wish to have a more robust persistence feature added to Store. I do that by extending the Store, and comes MyExtendedStore, which contains all features regarding persistence. Next week, client says it is better for the grid to be grouped. So I use GroupingStore. But does it have the persistence features of the MyExtendedStore? No. So, extend MyExtendedStore, so that we have a new class MyExtendedGroupingStore so that it could have its features. But what if I used JsonStore in some places, and still want that persistence feature; so again do the same thing? Even if the extending is about 4-10 lines of code, I'd prefer not to because it is in this cases which I think the Plug-In system is appropriate. In other words, Composition is better suited than Inheritance.

Or C.f. this post:
http://extjs.com/forum/showthread.php?t=55966

evant
26 Dec 2008, 11:01 PM
I only skimmed through this, however can I attempt to summarise?

You basically want plugins on classes that, at current, don't extend Ext.Component.

If so, I think your solution would make sense, so that the hierarchy would be:



Ext.util.Observable
Ext.Object
Ext.Component
Ext.data.Store
//etc


Obviously there are other things to consider. For example in 3.0 you can specify the type of the store as a string and have it be created.

eccehomo
26 Dec 2008, 11:29 PM
I only skimmed through this, however can I attempt to summarise?

You basically want plugins on classes that, at current, don't extend Ext.Component.

I cannot be more happy that FINALLY someone understood what I have been trying to explain. And not just somebody, someone from Ext (of course everyone is just as important here :D).

Yes. That is precisely what I wish for in the coming versions of Ext. To me, the Ext.Component family is extensible as it can be. One can extend, write plugins, or even even override.

But as for Store, currently one cannot write plugins. We are removing a basic feature from Store: composition, delegation (through a separate manageable class) as successfully achieved by Plugins in the Widget(Ext.Component) family/package.



If so, I think your solution would make sense, so that the hierarchy would be:


Ext.util.Observable
Ext.Object
Ext.Component
Ext.data.Store
//etc


Yep. That is the proposed hierarchy.



Obviously there are other things to consider. For example in 3.0 you can specify the type of the store as a string and have it be created.

I cannot be more excited about that. And are there some plans on revising the hierarchy, as what you proposed above? Honestly, to me the "string type" for stores is fully encapsulated already in xtypes. A little revision for ComponentMgr and Ext.Object for that matter (if the hierarchy is revised), should suffice in building a store based from a "string" or "xtype".

Thoughts?

(p.s. My previous posts, I realized, are very long and hard to read. I apologize about that. I was extensively defending a suggestion which was in danger of being misinterpreted. I do not want that to happen, at least some intelligent discussion must ensue.
Much of the ideas are summarized in my last two posts (excluding this one). Thanks.
)

SamuraiJack1
27 Dec 2008, 1:10 AM
Take a look here: http://extjs.com/forum/showthread.php?t=55968

With this bridge you can apply Roles (aka class-level Plugins) to any of your classes - including standard Ext classes, like Ext.data.Store, etc

eccehomo
27 Dec 2008, 2:15 AM
Yeah thanks, I looked at it already. The problem I found though was with time :D. I cannot at this moment try new things; I'd rather wait for the official Ext response on this issue. It seems like an elegant workaround though.

Thanks for the help.

SamuraiJack1
27 Dec 2008, 2:25 AM
Thats it - elegant and unified )

mjlecomte
27 Dec 2008, 6:42 AM
I cannot be more happy that FINALLY someone understood what I have been trying to explain. And not just somebody,
Please don't confuse misunderstanding with efforts to get you away from talking about Component.



For something like you're saying here to work, you'd need to ...have Observable implement it anyway?

Why implement another "type" ("otype") when we have the powerful "xtype"? If I'd go that way, I'd just be adding something to learn about, which does not make sense anyway because its basically the same thing: A COMPONENT TYPE (non-visual/widget at that).
Your proposal is what I was saying, but you dismissed it. You were insisting implementing this on the store.load() method to initPlugins(). But I had stated that you should be doing this higher up on the food chain...at Observable.

Again, as the above quote shows you were insisting on xtypes and Component, which doesn't make sense.

You got the answer you wanted in the form you needed, so I guess that's all that matters at this point.

eccehomo
27 Dec 2008, 9:16 PM
Please don't confuse misunderstanding with efforts to get you away from talking about Component.

What? I can't make sense of that remark.
Again, to me, when Ext say's "This is a Component", it is not something final. I want to hear from the Ext Team about this. Being a "Component" in a framework, for any Framework for that matter, is just as arbitrary, and conventional as in versioning schemes. I am simply suggesting that the classes in Ext.data Package be also treated as "components" for the reasons that I have stated in the previous posts, which you seem not to understand.



Your proposal is what I was saying, but you dismissed it. You were insisting implementing this on the store.load() method to initPlugins(). But I had stated that you should be doing this higher up on the food chain...at Observable.


I'm sorry if you indeed suggested a proposal. But, perhaps from my problematic reading skills, I misread everything you wrote. If you please, could you refer to that post? I have quoted you right from the start, so that isn't hard to follow.

Why should I do it on Obsrevable? My problem is on the initialisation of plugins. If I'd to that on observable, I'd be affecting Ext.Component. I have no problems with Ext.Component as far as plugins initialisation is concerned. So, I'd do it (the override) on Ext.data.Store because that's where the lack is. What is wrong with doing it on the load() method? If you have better ideas, present it. I did it on the load() and loadData() method, because those methods are likely to be called upon a store's lifetime. If you read that code, initPlugins is run only once, because after it is called, I set a tag (isPluginsLoaded) to true. Its use is whether to initialise plugins or not.

In fact, I could also do the plugins initialisation on StoreMgr by overriding the 'register' method. Now I will give that a consideration since I haven't tried it yet. The only problem is, that a store instance must be explicitly given an id ( which perhaps is a good practice) so it could be registered on StoreMgr.

You might wonder, "Why not on Store's constructor?" But then again, that would be extending the store, which what I am trying to avoid. Unless of course you show me a way of overriding an existing class's constructor, which might be of help.



Again, as the above quote shows you were insisting on xtypes and Component, which doesn't make sense.

If you had read my arguments on xtypes and component's, perhaps you could comment on that? What does not make sense? COuld you show it to me please, so that others could follow? I never "insisted" on xtypes or components. I merely pointed out that xtypes are applicable to the Ext.data Package as well because, to me, classes in the Ext.data package are components as well, but only they do not extend the DOM (why should they? - they are data-related classes).



You got the answer you wanted in the form you needed, so I guess that's all that matters at this point.

No. The Ext Team hasn't had yet commented if someday, the Ext.data and Ext.Component family might inherit, aside from observable, a common class, as what evant pointed out. Or, if the initialisation of plugins might be re-factored to Observable.

Again, sorry, if you feel that you have answered me. But none of your answers had the similar nature with evant, nor samuraijack. To me, you kept pointing and offering irrelevant sources and remarks.

At this particular point, I was not really looking for 'answers'. I was hoping to engage into an intelligent discussion and consideration of the Ext architecture, on its current form, and to where it is headed.

I feel that if we find it useful wrting plugins on 'visual components' (i.e, Ext.Component family), why not for 'non-visual components'? (i.e, Ext.data package)?

I do not believe someone never-ever wished wished that they could extend a Store in a similar manner as you extend a Grid, by just writing a plugin. Sure you could Ext.extend STore, but then again, that would be Extending, which implies that you lose to apply your fixes/added-features/etc to subclasses/descendants of the class you Extended. If you Extend Store, your code does not apply to GroupingStore, JsonStore, etc. What is appropriate is composition and/or override. You just, as saki would say, roughly quoted, "plug into it". New feature, plug a class; remove a feature, "unplug" a class. How hard could that be? Currently, my workaround is to override Store. What I wish, and wonder, if this override would be proven unnecessary in the future releases, because the Ext.data package natively supports plugins just as the Ext.Component family does.

evant
27 Dec 2008, 9:54 PM
Obviously it's something we'll need to look at a bit more closely. While 3.0 will have some breaking changes, we will want to avoid doing so needlessly, or causing people to have to refactor large amounts of code when upgrading to the new version.

I can see there would be benefits of this, one of which would be the ability to follow a similar onInit() onDestroy() template pattern that is used for component and its subclasses.

However, we'll need to review this and see what kind of implications it may or may not have. Feel free to continue discussing and developing this idea, I'll keep checking it out.

eccehomo
27 Dec 2008, 10:16 PM
@evant
Thanks. I understand. I myself do not want to change a lot of code :D. The discussed/proposed revision is high on the hierarchy, so obviously, almost all classes are to be affected. All the same, I am vehement to know what others think.


I came up with this patch, though. I am not sure what this implies with instances of Store. I'd appreciate it if you tell me the problems with this:


/*
the strategy is as follows:
1.)
onStoreConstruct
Why not utilise StoreMgr? It's been sitting there all the while.
But, for a store to be registered on StoreMgr's registry,
it must have a storeId or id. So, create an interceptor of store's constructor, and ensure that it has such property.

2.)
onStoreRegister
when the store is registered, check to see if it has plugins. as simple as that.
*/

/*
This class adds a capacity for the Store class (and all its descendants)
to have plugins installed on them
*/

Ext.ns("Ext.ux.data.patches");

Ext.ux.data.patches.StorePluginsPatch = function(){

return {

//private
onStoreConstruct : function(config){
//provide an id if non is supplied, so that it'd
//be registered in the StoreMgr
config = config || {};
if( !config.id ){
config.id = Ext.id();
}
},

//private
onStoreRegister : function(){
var initPlugin = function(plugin, store){
if( plugin.xtype && typeof plugin.init !== 'function' ){
plugin = Ext.ComponentMgr.create(plugin);
}
var p = plugin.init(store);
return p;
}

for(var i = 0, len = arguments.length; i < len; i++){
var store = arguments[i];
if(store.plugins){
if( Ext.isArray(store.plugins) ){
Ext.each(store.plugins, function(x,y,z){
store.plugins[x] = initPlugin(x, store);
}, this);
}
else{
store.plugins = initPlugin(store.plugins, store);
}
}
}
},

installPatch : function(){

//"install listeners" by adding function interceptors
Ext.data.Store.prototype.constructor = Ext.data.Store.prototype.constructor.createInterceptor(this.onStoreConstruct, this);
Ext.StoreMgr.register = Ext.StoreMgr.register.createInterceptor(this.onStoreRegister, this);
}
}
}();
Ext.ux.data.patches.StorePluginsPatch.installPatch();


//the sample plugin
Ext.ux.data.plugins.Plugin1 = function(config){
Ext.apply(this, config);
}

Ext.ux.data.plugins.Plugin1.prototype = {
init : function(store){
//install listeners, interceptors, sequences, delegates just as we would write a plugin for the Ext.Component family
},

//some method we want other stores in our application to have.
method1 : function(){

}
}
Ext.reg('store_plugin', Ext.ux.data.plugins.Plugin1); //so it could be used with xtypes

//now we could:
var store = new Ext.data.Store({
.
.
plugins : [new Ext.ux.data.plugins.Plugin1({})]
.
.
});

//or (using xtypes)
var store = new Ext.data.Store({
.
.
plugins : [
{xtype : 'store_plugin'}
]
.
.
});

eccehomo
27 Dec 2008, 10:24 PM
@evant.
One benefit I see of course is extensibility. Ext does not need to be worried too much on the Data side as the community keep on writing codes and plugins that are too complex to be supported by Ext but are helpful to the community in general. In business applications, for instance, data manipulation is complex and yet very specific. Ext of course, as a framework, must stay agnostic with each application's data structure; let the developer implement it. At least, the community will have the chance "to do their own" on this issue, but of course with care.

The implication really is "extensible data structures/models of Ext applications" (which does not imply that currently we can not do so. The level of possibility though is somewhat limited, but very attainable). Of course, one might argue, that all things related to data must be on the server. But at least in some way, it will end up in representations (grids, listviews, trees) and that's the concern of Ext. If data on the server ends up on the client, then likewise should the data layer on the client (the Ext.data package) be able to handle the complexity of the server.

Currently Ext, and its community, has done a great job on "extensible data presentation of Ext applications".

And regarding xtype. To me, it is sufficient as it is. We can interpret an xtype as the "primary key" of the set of all Ext classes and community Plugins (together with namespacing). If it is applicable to the Ext.Component family, what's the difference or issue with applying it with the Ext.data package or community plugins for that matter? Why introduce another "primary key", when one should suffice? I feel that there is no need to invent another "types", or "create a new primary key". Before we know it, we might have too many types, which only breeds confusion, support, needless questions, etc.

But of course, these are mere suggestions which I hope are sensible to the Ext Team.

eccehomo
28 Dec 2008, 8:49 AM
It occurred to me that if there are disagreements on 'types' (xtypes, ptypes), Ext should provide a point of agreement. How? Introduce default types.
Perhaps we can:



Ext.reg('atypename', AClass, 'thepropertyoftheclass');

Such that if we have:


AClass.prototype = {
ptype : 'blah'
};

Or:


AClass.prototype = {
xtype : 'blah'
}

no conflict occurs (at least in usage and preferences).

The "default" type of course, should be configurable like Ext.DEFAULT_TYPE. It is upto Ext on what should be the initial value.

My request still holds though: (1) Ext.data package allowed to have types. (2) Plugins not restricted to "ptypes" (as some would desire). And perhaps a third, other types of "types" are needless.

The implication of not having a type or identifier for any usable class released OOB by Ext (e.g., Ext.data, Grid) is that the Factory Pattern (as implemented by ComponentMgr.create) is limited only to some classes. Not to all classes.

eccehomo
12 Jan 2009, 9:19 PM
Out of curiosity, evant what is the news on allowing to write plugins for the Ext.data package?

Thanks.

eccehomo
15 Apr 2009, 9:36 PM
Since 3.0 is still a candidate release, I might as well share some comments on issues that are not really that crucial.

First would be 'ptypes'. This has been brought up before, and the usual answer is: "Well, ptypes are for plugins.". It's obvious of course, what 'ptypes' are for. The question is not "what is a ptype", or "What are ptypes for?"

Rather, the question is: What's the difference in purpose between a 'ptype' and an 'xtype'; is there something in 'ptypes' that cannot be addressed by 'xtypes'? Are there problems/issues which 'ptypes' alone can solve, and 'xtypes' cannot? Because if there is none, I'm afraid 'ptypes' are a redundant feature; redundancy of course can lead to several problems, which ought to be avoided in its first appearances.

mjlecomte
16 Apr 2009, 4:49 AM
Plugins are instantiated differently from Components. Plugins are being registered and collected separately from Components. There are several id's (PropertyId, StoreId, ItemId, etc.) used to help the developer distinguish similar property characteristics used for different classes.
The one that seems confusing to me is using a xtype in the Column Model.

eccehomo
18 Apr 2009, 2:17 AM
Plugins are instantiated differently from Components.

Why are they instantiated "differently"? To me, plugins are jscript classes, too, so, they aren't "different" with Components. If you mean, they are to be instantiated differently, as fas as Ext is concerned, then why?


Plugins are being registered and collected separately from Components.

Again, why? For what purpose other than "to help the developer distinguish..."? Is that need not achieved, currently, by 'xtypes'? If it is achieved, why is this method still introduced? Would this not lead to future code-bloat?


There are several id's (PropertyId, StoreId, ItemId, etc.) used to help the developer distinguish similar property characteristics used for different classes.

Why should there be different field/property name for the same things (namely, identification purposes)? Should it not be enough that when we want to distinguish an object we refer to the 'id' property alone and not to other adhoc names (e.g., storeId, xID, etc)?



The one that seems confusing to me is using a xtype in the Column Model.



I see no logical reason for not doing so.
Consider:


new Ext.grid({
cm : [{
xtype : 'cmodel',
cols : [....]
}]
});

It is just a matter of syntax.

Animal
18 Apr 2009, 2:23 AM
The xtype is for disambiguating what kind of entity needs to be instantiated when presented with a raw object hash of configs.

For the cm config, it's always going to instantiate an Ext.grid.ColumnModel.

eccehomo
18 Apr 2009, 10:43 AM
The xtype is for disambiguating what kind of entity needs to be instantiated when presented with a raw object hash of configs.

Again, I see no reason for why not applying that to the 'usual' Ext classes (e.g Ext.Component family, etc..).. If "disambiguating what kind of entity" is applicable to the 'usual' ext Classes, then, theoretically, that should be applicable to user-classes too (e.g plug-ins, extensions, etc.). And so, there should be no need of other methods to achieve the same effect. Introducing other methods to achieve the same effect is redundancy, don't you think so?


For the cm config, it's always going to instantiate an Ext.grid.ColumnModel

Obviously.
I was trying to illustrate that doing so is not logically incorrect. Of course it's impractical to introduce that a ColumnModel should have a 'xtype'. But "impractical" in the face of the current number of classes and the current code-base. But certainly, the concept of 'xtypes' per se is still applicable to the ColumnModel since the ColumnModel is a unique Ext Class which what xtypes are for: to mnemonically and uniquely name a class. Is not that achieved by 'xtypes' -- considering that xtypes are (Ext) Classes and plugins are Classes, too?


The issue I am trying to anticipate is when there is a need to use "a raw object hash of configs."

For consider:



Ext.create({
xtype : 'somevalidtype',
plugins : [{
ptype : 'someplugintype'
}]
});

//or
Ext.create({
xtype : 'somevalidtype',
plugins : [{
xtype : 'someplugintype'
}]
});

The second does not discriminate what you are using: whether a plugin or not it is still treated as a type (i.e as an xtype). The first use case discriminates what "kind" of class you are using. It does not treat classes uniformly. The implication is that, when you are trying to automatically generate a definition (i.e., a json config), you must be conscious of the 'type' of classes you are to use: but that "being conscious" is superficial (to me) because, in the first place, they are just Ext Classes (or js classes).

Comments?

deanna
18 Apr 2009, 12:06 PM
You may have a plugin that works with different Components. You can plug it into a panel, a window, TabPanel,... This is where the ptype is useful. You can specify a config object with the xtype that you need along with the plugin ptype you need. It is mix and match. It would be possible to create a new xtype for each of those classes with the plugin already there, but that isn't quite as clean or as versatile as the ptype mix and match.

mjlecomte
18 Apr 2009, 6:23 PM
You may have a plugin that works with different Components. You can plug it into a panel, a window, TabPanel,... This is where the ptype is useful. You can specify a config object with the xtype that you need along with the plugin ptype you need. It is mix and match. It would be possible to create a new xtype for each of those classes with the plugin already there, but that isn't quite as clean or as versatile as the ptype mix and match.

I think ecchemo is insinuating that everything that uses a config object should use an xtype, and anything that uses and "id" property should be called "id". It also seems he wants the mixed collections to be shared into one collection for plugins and components. Personally I think it would cause more confusion. There previously was a tendency to just use "id's" and the framework is migrating away from that because of the problems/confusion it caused before.

eccehomo
19 Apr 2009, 3:54 AM
You may have a plugin that works with different Components. You can plug it into a panel, a window, TabPanel,... This is where the ptype is useful.

I see no reason for not using 'xtypes' for that. Consider:


new Ext.TabPanel({
plugins : [{
xtype : 'somegenericplugin'
}]
});
new Ext.GridPanel({
plugins : [{
xtype : 'somegenericplugin'
}]
});
//etc.


Another consequence of this suggestion would be:


Ext.create({
xtype : 'some_plugin_type'
});

Ext.create({
xtype : 'some_extension_type'
});

Ext.create({
xtype : 'some_standard_type'
});


Indeed, we can use "Ext.create()" generically. Meaning, Ext.create (the default factory method in Ext) is not just limited to the classes OOB (or user extensions). They can be applied to anything without distastrous consequences; so long as the js class concerned is registered using "Ext.reg".

In general, the implication is that I need not bother what 'type' is it that I am using; whether it be standard class, a plugin class, an extension class. As far as the Ext framework is concerned, the 'xtype' config should suffice. What motivates this request is to avoid confusion.


You can specify a config object with the xtype that you need along with the plugin ptype you need. It is mix and match.

That is what I am trying to avoid: the "mix and match". Practically, if we want to instantiate a class using a string, why can't we use just a single config property for that, namely, the 'xtype'?

eccehomo
19 Apr 2009, 4:15 AM
I think ecchemo is insinuating that everything that uses a config object should use an xtype,

Be careful with the "should". What I am suggesting (or noting) is that xtypes are sufficient and ptypes are needless, for the reason that what is achieved by ptypes are already achieved by xtype. A slight tweaking in the current source code should achieve this effect. Of course, it is up to the developer what xtypes s/he needs, as appropriate in his/her situation.

For instance, ColumnModel xtypes might not apply to her; but if in the future it would turn out to be so, then it should be convenient to build a ColumnModel class by just using Ext.create: the Ext.create facility should come in handy. The same principle should apply for Plugins too.

(Note: I believe these belong to a separate topic, but I will still reply here for convenience.)


...and anything that uses an[d] "id" property should be called "id".

I don't get that, frankly.
But perhaps it was about the Ext.data.Store by using 'storeId' and not 'id'. But that is a different topic.



It also seems he wants the mixed collections to be shared into one collection for plugins and components.

I see no logical reason why this should not be the case. But I am not "proposing" that for practical reasons - and only for practical reasons.



Personally I think it would cause more confusion.

Why? I presented my reasons and arguments in what I believe to be my best shot for logical reasoning. Is my being logical causing confusion?



There previously was a tendency to just use "id's" and the framework is migrating away from that because of the problems/confusion it caused before.

Can you state the situations? I might be ignorant of those. It might shed some light. But then again that concern is separate from the 'ptype/xtype' issue which is the current topic of this thread - albeit very related, but ultimately different. The irony is that I am proposing/noting these things to avoid confusion . And mjlecomte thinks it would result to the opposite! Hmm.. I really am wondering what really is "confusing". My notion for not confusing is simple and fairly old: DRY: Don't repeat yourself

However, I am aware that the true issue here largely depends on use-cases and preferences. Such that it is a matter of community-preference what should, or how, things be. Of course, the relevant reasons might be "for convenience", or "it is practical". Well, I can't complain; and I won't for such state of affairs. After all, that is the essence of an open-source community/project.

But: As much as possible I would like to see that the agreed-upon, or conventional, methods (e.g whether ptypes, xtypes?; whether "ids" or "storeId", "tabPanelId") are consistent and clear (i.e, not confusing).

mjlecomte
19 Apr 2009, 4:18 AM
I think I'll recant my position on the ptype and agree that using "xtype" instead might be better.

I still can't say that for id though. I think history has shown it caused a lot of confusion. The prime example is store's I think when you're not sure if the id applies to the store, the record or what.

eccehomo
19 Apr 2009, 4:49 AM
I think I'll recant my position on the ptype and agree that using "xtype" instead might be better.

I must admit that I'm glad, after a long discussion with you, I made you reconsider. :) But then again, where all this leads is not for us individually to determine, but the community as a whole.



I still can't say that for id though. I think history has shown it caused a lot of confusion.
The prime example is store's I think when you're not sure if the id applies to the store, the record or what.

Now, honestly, I am confused why that confuses people. Consider this:



var aGrid = new Ext.GridPanel({
id : 'somegridid'
});
var aTab = new Ext.TabPanel({
id : 'sometabid'
});

var aStore = new Ext.data.Store({
storeId: 'somestoreId
});

Notice the sleight-of-hand there. What should be a fairly straight-forward assigning of id to an instance (object) is complicated by the fact that we can't refer to the same property to uniquely name an object across all classes. Meaning, I have to know what class I am currently using. (Note: Of course "we have to know what class we are to use." The point here is not that; rather, the method/mechanism of uniquely naming an instance of a class (the object) should be uniform across all classes; i.e, we don't need to know what class it is to achieve such effect for the sake of convenience and consistency.)

If we are to follow the scheme introduced in "storeId', this has unpleasant (IMHO) consequences.
Considering we are trying to be consistent with "storeId" pattern, then the way things are done should be like this:


var aGrid = new Ext.GridPanel({
gridId : 'somegridid'
});
var aTab = new Ext.TabPanel({
tabId : 'sometabid'
});
var anExtensionOfTab = new Ext.ux.CustomTabPanel({
customTabId : 'somecustomtabid'
});

var aStore = new Ext.data.Store({
storeId: 'somestoreId
});


Does that mean, that for every extension I have to make, I should re-introduce another field to hold the unique id of such a class? That would be very inconvenient and unnatural to me, IMHO.

mjlecomte
19 Apr 2009, 6:19 AM
As to the id's you will have to examine the store class closely. Store's accept configs that can belong to the store, reader, record, etc. So it has been a source of confusion for the end user and possibly core developer. Store does take an "id". But propertyId, and storeId were introduced because of confusion in the past.