Singletons Ext JS (4.2.1) and Stores - extjs

How do you implement a Store to be a singleton?
In Architect my store has a property checkbox that adds the property
singleton: true,
If I add that then reload the application it fails to load (I can give more details if required about error)
Uncaught TypeError: object is not a function VM5238:3
(anonymous function) VM5238:3
Ext.ClassManager.instantiate ext-all-debug.js:5485
(anonymous function) ext-all-debug.js:2109
Ext.define.getStore
If I then remove that property it loads fine, but where I use Ext.getStore("MyStore") then the stores that are returned contain different data depending on where I'm using the store. I have a single controller where I use the class name inside the getStore method and this is used in a couple of functions inside that one controller.
Also there does not appear to be any documentation about the singleton property in the docs. If I look at Ext.data.Store there is no singleton.

I recommend you to do it the ExtJS way for handling stores and store instances...
Use the storeId along with the Ext.StoreManager. Note that each storeId need to be unique and as soon as you create a instance of a store it will register itself into the Ext.StoreManager with its storeId. You can get a store by calling the lookup('storeId') on the Ext.StoreManager. And yes you can do that from anywhere in your code.
For example all Ext.Components that mixin Ext.util.Binable (which are most (all) native components that bind a store) will be fine with the storeId string assigned to the store cfg property. The Binable mixin will internally lookup it from the StoreManager. If you need to do it yourself
//...
store: Ext.StoreMgr.lookup('storeId') || Ext.create('YourStoreClassname')
//...

Related

Multiple classes in Ext JS to update and share the same config settings

I am fairly new to using Ext JS 4.0.7, and have recently discovered the Config options, so I have set up the following config class, which initialises with the following:
Ext.define('CurrentRowSelection', {
extend: 'Ext.app.Controller',
config: {
currentAccountID: {
$value: 'Empty',
cached: true,
evented: true
}
},
initialize: function(config) {
this.callParent(config);
}
});
I am able to update this config quite nicely from another class's listener event, which is right clicking on a row record and grabbing the currentAccountID value. However, every time I try to access the new, updated, config from a new class after initialising - it keeps reverting back to the 'Empty' value.
The following is used to set the config from the class containing the listener:
var CurrentRowSelection = new CurrentRowSelection();
CurrentRowSelection.setCurrentAccountID(1);
However, when I create a new constructor in a new class, with the hope of accessing this newly updated config from elseware, my console.log is telling me that it is continuously reverting back to the default values, as it seems to be initialising each time a new constructor is created - which makes sense, but I need to stop it.
How can I do thisand make sure that this value is saved all the time, every time? Thank you.
Don't make new controllers every time. Every controller should be instantiated only once, because if you instantiate multiple controllers of the same type, every event binding you prepare in the control method is executed multiple times (the control method usually is the most important method of a controller, although there may be exceptions.)
So every controller should exist as a single instance only, and that singleton would be accessed using getController wherever and whenever you need it:
MyAppName.app.getController("ControllerName").setCurrentAccountID(1)
That said, I would recommend to look into using stores for data storage, not controllers. Stores offer the possibility to synchronize the settings with a server (create, read, update, delete). If you want to create a singleton store, you would give it a storeId and use Ext.getStore() to access the store.
For example, the config settings in my application are in the first record of the store with storeid AllSettings:
Ext.getStore("AllSettings").getAt(0).get("groupDiscoveryCacheHours")

Best practice to have the same view and store multiple times in ExtJS 4

I would like to have different instances of the same view with different stores at the same time in an ExtJS application. At the moment i ceate multiple instances of the same view (Ext.view.View) in the viewport.
But what is the best practice to have a different store in every view? Every example that i found uses a Store-ID in the view that was created using the stores-Config of the controller. But this would use the same store for every view.
At the moment i figured the following possible solutions:
Create an own store class for every view instance. Add all stores to controller and use different Store-ID for every view instance.
Do not use stores of controller at all and create a new store in the initComponent of the view manually passing different parameters to each instance of the store.
Do not use stores of controller at all and create a new store in the initComponent of the view manually. Then use load to load the store manually using different parameters for each instance of the store.
Is any of this solutions the best practice or should it be done differently?
The thing with the stores array of the controller
is, that it will override any storeId defined. After loading the store class the controller set the storeId by a namespace convention, create the store and create the getter method method by using the value as the soreId.
Let me introduce option 4
Define one store for the view and require it in the view (you can also require it within the controller, just use the requires array).
Choose valid itemId's for the views and valid storeId's for your store that should depend on the itemId of the view (set it when creating the view!).
Within the initComponent create the storeId and lookup the store in the StoreManager. If it not exist create it and supply a Customer config and the storeId.
If you need to destroy the view and the store each time take a look at this post
Demo initComponent
initComponent: function() {
var me = this,
storeId = me.storeId + me.itemId;
me.store = Ext.StoreManager.lookup(storeId);
if(me.store === null)
me.store = Ext.create('App.data.CustomViewStore',Ext.apply({storeId: storeId},me.storeCfg || {}));
me.callParent(arguments);
}
Note: If you load the view with the views array you will end up with a getter that may not give you the view you expected. You may use the requires array of the controller here, too. If you want to use getter simply create your own one by using the refs config.

Backbone.js - Properties vs Attributes

What is the difference between properties and attributes of a Backbone model.
I believe one would use attributes to trigger model changes when the model gets modified.
In the below example.
var Vehicle = Backbone.Model.extend({prop1:'1'});
var v1 = new Vehicle({prop1 : '1111'});
console.log(v1.prop1); // accessing the property
console.log(v1.get('prop1')); // accessing the attribute
The object v1 has both a property called prop1 and also an attribute called prop1. There is no relation between them.
The difference is really that a property is a language feature (Javascript), whereas an attribute is a feature of the Backbone framework. To put it another way, a property exists independently of Backbone, whereas an attribute relies on the Backbone framework and its infrastructure.
Specifically, attributes participate in all the model-related things:
sync (when you call save or fetch)
validation on save
view rendering (via toJSON)
events and notification

For what do I use the appProperty property?

I recently stumpled over the appProperty within the the Ext.app.Application class and wondered why would I use it. I would require access to App instance anyway to then access a variable that again contains the instance? Maybe I am stupied but for what is this property?
I guess you have a misunderstanding here; The name property just defines a namespace of the Application along with a getter Method for it (getApplication()) but it will not provide you with the current instance of that application unless you call the getter or use the new appProperty.
Lets say you have the following application
Ext.application({
name: 'App',
appProperty: 'instance',
launch: function() {
// some more code
}
});
the you can access this application from any Component by calling either
App.getApplicatio();
or
App.instance
Where the second will be bit faster cause it is no method call and for sure you can define the name of this property. So I guess you see this property is quite useful!
Note that a namespace is always a object in javascript. That is the
reason why you are able to place properties into it.

How to find Table and append a new record to its Store?

I need to update a Store based on some information that I have.
I have a table in the document, that uses some Store to keep data,
and in separate part of page I have a button that needs to add some information to the Store (and table). I got a bit confused, so, I just ask here all I need to know:
Which property in table configuration needs to be specified to locate table later?
Which call I need to make to find the table and locate its store?
How I can generate and append data to the table's existing store?
The "table" you are referring to is Grid in ExtJS terminology.
1. To get the grid for later use, you need a reference to that object. There are many ways in ExtJS to get hold of this reference.
Using Javascript Variables: Most simple way is to have a javascript variable that will hold the reference. This is usually done when the grid is created. For example:
var myGrid = Ext.create('Ext.grid.Panel', {
// All the configs...
});
You can use the myGrid variable to get access to the grid.
Using ComponentManager: When an ExtJS component is created, it gets registered with the component manager. You can always get hold of an ExtJS component from this register. The manager tracks each component with a unique id. To use this method, you will have to define a unique id for your grid component and later use the famous Ext.getCmp() method. Here is an example:
var myGrid = Ext.create('Ext.grid.Panel', {
id: 'myGrid', // Unique id for the grid
// All other configs...
});
Using this method is NOT the best practice.
Using itemId and Component Query: A better method than the above two; you can use the itemId config and ComponentQuery. ComponentQuery class provides a selector-based searching for Sencha Components analogous to DOM querying. Example:
var myGrid = Ext.create('Ext.grid.Panel', {
itemId: 'myGrid',
// All other configs...
});
And to get a reference, you may call the query() method from a container or use Ext.ComponentManager (this is global).
Accessing in MVC controller: If you are developing your application using MVC, you can make use of this method. A controller have reference array namely: refs. (Internally, the method makes use of ComponentQuery and selectors to access the component). Refer MVC guides and examples to see how this works..
2. Once you obtain the grid with any the above techniques, you can get the store simply by calling the method: getStore(). This returns the store object (Ext.data.Store). Example:
myStore = myGrid.getStore();
3. Refer the Ext.data.Store documentation. you can manipulate your grid's store using methods like add(),load(),remove() etc...
FYI.
It is not
Ext.Cmp()
it is
Ext.getCmp('myGrid')

Resources