PDA

View Full Version : config getters and setters not working as expected



wilcosch
8 Jul 2015, 4:59 AM
I am in the process of building a treepanel but ran into some issues. I want to create the treepanel with a certain context variable and also be able to change the context on the fly. The context here is depicted as the 'root' node of the tree. I want to make use of the class config with auto-generated getters and setters:




treepanel = Ext.create("MyApp.view.Tree2", {contextVar: "left"});
treepanel.setContextVar("right");



The following is a stripped down version of the prototype to isolate the problem:




Ext.define('MyApp.model.Tree2', {
extend: 'Ext.data.TreeModel',


fields: [
{ name: 'name' },
{ name: 'value' }
]
});


Ext.define('MyApp.store.Tree2', {
extend: 'Ext.data.TreeStore',


model: 'MyApp.model.Tree2',


config: {
contextVar: null
},


proxy: {
type: 'ajax',
api: {
read: '/prototype/tree_read/'
}
},


// Constructor structure
constructor: function (config) {
// jshint strict:false
this.callParent(arguments);


this.initConfig(config);
},


setContextVar: function (contextVar) {
'use strict';


this.contextVar = contextVar;


this.setRootNode({id: contextVar});
}
});


Ext.define('MyApp.view.Tree2', {
extend: 'Ext.tree.Panel',


config: {
contextVar: undefined
},


columns: [{
xtype: 'treecolumn',
text: 'Property',
dataIndex: 'name'
}, {
text: 'Value',
dataIndex: 'value'
}],


initComponent: function () {
// jshint strict:false


this.store = Ext.create('MyApp.store.Tree2', {
contextVar: this.contextVar
});


this.callParent(arguments);
},


setContextVar: function (contextVar) {
'use strict';


this.contextVar = contextVar;


this.getStore().setContextVar(contextVar);
}
});



This code works and I am able to 'reload' the tree on the fly, however trying to expand on this gives some problems.


Question 1: Why is the override of the tree store constructor needed? Without it the custom setter is not called, which in turn fails to load the store.


Question 2: Trying to use the same constructor override in the tree view gives conflicts with initComponent. However, currently the config is not initialized properly. Calling the getter on the view for the first time shows the problem and actually 'resets' the configuration.




> treepanel = Ext.create("MyApp.view.Tree2", {contextVar: "hoi"})
< constructor {enableAnimations: true, contextVar: "hoi", initialConfig: Object, events: Object, autoGenId: true…}
> treepanel.contextVar
< "hoi"
> treepanel.getContextVar()
< undefined
> treepanel.contextVar
< undefined



Question 3: What is the correct way of using and combining constructor, initComponent and initConfig?


Thanks in advance!

LailaAgaev
9 Jul 2015, 7:11 AM
I'm not an expert but I believe you are not using config correctly?

In general I think the problem you are seeing may be solved by doing the following. Don't do this:



setContextVar: function (contextVar) {
'use strict';
this.contextVar = contextVar;
this.setRootNode({id: contextVar});
}

You should not override the set method. Instead, override the update (which is called AFTER set) or apply (which is called BEFORE set, and may change the value) methods. Example:


applyContextVar: function (contextVar) {
//at this point, contextVar is not set yet!
//this.getContextVar() will not return the above value!
//if you need for contextVar to be set and THEN execute some code,
//use updateContextVar function instead!

this.setRootNode({id: contextVar});

//the return statement determines what is actually set as the contextVar,
//if you return nothing undefined is set!
return contextVar;
}

Following this, the correct way to access contextVar, is only using the getter: this.getContextVar(). using the properly this.contextVar is not correct (unless you explicitly set this.contextVar in the apply/update methods, but Ext 4 will also set it automatically internally, and Ext 5 will not set it at all! Better to avoid it entirely).

About initComponent, initConfig, and constructor, I may be wrong, but...

(1) initComponent is called after the config is already set and should not have anything to do with config in it. At this point you should be able to use config getters / setters, and all values should be pre-set.

Keep in mind, when you call this.callParent(arguments) in the constructor, that eventually calls initComponent. So if you must manually initialize the config, do so in the constructor before the callParent, otherwise initComponent will be called with config not initialized

(2) constructors for Ext.Component (and any extensions of it like Panel, treePanel, etc) will call initConfig internally. You don't need to do so and it may mess up the config lifecycle a little, especially if you call it after constructor's callParent.

(3) I think that the TreeStore constructor may also initialize config automatically, but maybe I'm wrong. If you find the config is not initialized (after fixing the above issues), you may need to call initConfig manually BEFORE calling this.callParent(arguments) in the TreeStore constructor.

I hope someone corrects me if any of this is wrong...

radu1204
22 Jul 2015, 7:21 AM
I am also interested in this.