ExtJs4 How to assign a model to a store at creation? - extjs

I'm defining a store and I want to dynamically assign a Model for it at creation. So if I create my DropDownStore and I don't pass a model config with it it needs to rely on the default model(DropDownModel).
Here is my DropDownModel + DropDownStore:
Ext.define('DropDownModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'Name', type: 'string' }
]
});
Ext.define('DropDownStore', {
extend: Ext.data.Store,
proxy: {
type: 'ajax',
actionMethods: { read: 'POST' },
reader: {
type: 'json',
root: 'data'
}
},
constructor: function(config) {
var me = this;
if (config.listUrl) {
me.proxy.url = config.listUrl;
}
me.model = (config.model) ? config.model : 'DropDownModel'; //This line creates some weird behaviour
me.callParent();
//If the URL is present, load() the store.
if (me.proxy.url) {
me.load();
}
}
});
This is a creation of the DropDownStore with a dynamic model:
Ext.define('RelationModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'RelationName', type: 'string' },
{ name: 'RelationOppositeName', type: 'string' }
]
});
...//a random combobox
store: Ext.create('DropDownStore', {
listUrl: 'someprivateurl',
model: 'RelationModel'
})
...
When I edit the line in the constructor method to
me.model = (config.model) ? config.model : undefined
It works like expected for the dynamic model but not anymore for the default models.
If I let it be
me.model = (config.model) ? config.model : 'DropDownModel';
It works for the default models and not for the dynamic model.
How can I assign a model to a store at creation?

constructor: function(config) {
var me = this;
if (config.listUrl) {
me.proxy.url = config.listUrl;
}
me.callParent();
if (config.extraFields) {
me.model.setFields(config.extraFields);
}
//If the URL is present, load() the store.
if (me.proxy.url) {
me.load();
}
}
store: Ext.create('DropDownStore', {
listUrl: 'someprivateurl',
extraFields: [
{ name: 'Id', type: 'int' },
{ name: 'RelationName', type: 'string' },
{ name: 'RelationOppositeName', type: 'string' }
]
}),

Related

PullRefresh plugin of a List doesn't handle ChainedStore possibility

Using Ext JS 7.1 Modern, I have prepared an example to show the problem.
When I have remote filters on my main store, binding the dataview.List to a ChainedStore correctly handles my local filtering. However, when I also add a PullRefresh plugin to the list, I get an error during pull refresh. I see from the source code that the plugin doesn't consider the possibility that a list's store can be a ChainedStore.
I have tried to explain the problem with a Sencha Fiddle and also attached the code below.
I have temporarily solved the problem by overriding the fetchLatest and onLatestFetched methods of Ext.dataview.pullrefresh.PullRefresh plugin, to use the source store if the list's store is a ChainedStore. But I believe the source code must be updated to handle this case.
app.js
Ext.define('App.model.Test', {
extend: 'Ext.data.Model',
fields: ['id', 'firstName', 'lastName']
});
Ext.define('App.store.Test', {
extend: 'Ext.data.Store',
alias: 'store.teststore',
model: 'App.model.Test'
});
Ext.define('App.viewmodel.Test', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.test',
data: {
query: ''
},
stores: {
test: {
type: 'teststore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'names.json',
reader: {
type: 'json',
rootProperty: 'data'
}
},
remoteFilter: true,
filters: {
property: 'id',
value: 1
}
},
chained: {
type: 'chained',
autoLoad: true,
source: '{test}'
}
}
});
Ext.define('App.controller.TestController', {
extend: 'Ext.app.ViewController',
alias: 'controller.testcontroller',
doSearch: function (field) {
var list = this.lookup('list'),
store = list.getStore(),
value = field.getValue();
if (Ext.isEmpty(value)) {
store.removeFilter('firstName')
} else {
store.filter([{
property: 'firstName',
value: value,
operator: 'like'
}])
}
}
});
Ext.define('App.dataview.TestList', {
extend: 'Ext.dataview.List',
xtype: 'testlist',
viewModel: {
type: 'test'
},
plugins: [{
type: 'pullrefresh',
mergeData: false
}],
emptyText: 'Name not found',
bind: {
store: '{chained}'
},
itemTpl: '<div class="contact">{id} <b>{firstName} {lastName}</b></div>'
});
Ext.define('App.MainView', {
extend: 'Ext.Panel',
controller: 'testcontroller',
fullscreen: true,
viewModel: {
type: 'test'
},
items: [{
xtype: 'searchfield',
ui: 'solo',
placeholder: 'Search names',
listeners: {
buffer: 500,
change: 'doSearch'
},
bind: {
value: '{query}'
}
}, {
reference: 'list',
xtype: 'testlist'
}]
})
Ext.application({
name: 'App',
mainView: 'App.MainView'
});
names.json
var data = [{
id: 1,
firstName: 'Peter',
lastName: 'Venkman'
}, {
id: 2,
firstName: 'Raymond',
lastName: 'Stantz'
}, {
id: 3,
firstName: 'Egon',
lastName: 'Spengler'
}, {
id: 4,
firstName: 'Winston',
lastName: 'Zeddemore'
}]
var results = data.filter(function(record) {
if (params.filter) {
return record.id > params.filter[0].value
}
})
return {
"success": true,
"data": results
}
App.override.dataview.pullrefresh.PullRefresh:
Ext.define('App.override.dataview.pullrefresh.PullRefresh', {
override: 'Ext.dataview.pullrefresh.PullRefresh',
privates: {
fetchLatest: function() {
const store = this.getStore().isChainedStore ? this.getStore().getSource() : this.getStore()
store.fetch({
page: 1,
start: 0,
callback: this.onLatestFetched,
scope: this
});
},
onLatestFetched: function(newRecords, operation, success) {
var me = this,
list = me.getList(),
store = list.getStore().isChainedStore ? list.getStore().getSource() : list.getStore(),
length, toInsert,
oldRecords, newRecord, oldRecord, i;
if (success) {
if (me.getMergeData()) {
oldRecords = store.getData();
toInsert = [];
length = newRecords.length;
for (i = 0; i < length; i++) {
newRecord = newRecords[i];
oldRecord = oldRecords.getByKey(newRecord.getId());
if (oldRecord) {
oldRecord.set(newRecord.getData());
}
else {
toInsert.push(newRecord);
}
}
store.insert(0, toInsert);
}
else {
store.loadRecords(newRecords);
}
me.setLastUpdated(new Date());
}
me.setState('loaded');
list.fireEvent('latestfetched', me, toInsert || newRecords);
if (me.getAutoSnapBack()) {
me.snapBack(true);
}
}
}
})
Thanks in advance
Since this post, instead of being a question, was a bug report with a possible solution, it has been posted to Ext JS 7.x Community Forums\Ext JS 7.x Bugs.
The above solution, that overwrites the plugin where source store is needed, works if anyone comes across the same issue.

ExtJs Grid Auto Refresh using REST Proxy

I have tried to refresh the Grid every 5 or 10 seconds which is using REST Proxy, but the grid is not getting refreshed more than once. Please find the code which we have tried.
Ext.define('App.Store.DeviceStore', {
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'app.store.DeviceStore',
model: 'App.model.DeviceModel',
activeRefreshTask:false,
pageSize: 5,
autoLoad: {
pageSize: 5
}
}, cfg)]);
},listeners:{
'load':function(store,records,successful,operation){
if(successful === true && store.activeRefreshTask === false){
var task = {
identifyId: 'deviceListStore',
run: function() {
if (App.app._currentPage == 'devicesform') {
store.reload();
} else {
Ext.TaskManager.stop(this);
}
},
interval: '10000'
}
Ext.TaskManager.start(task);
store.activeRefreshTask = true;
}
}
}
});
The model for the above store is
Ext.define('App.model.DeviceModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.String'
],
proxy:{
type:'rest',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty:'total'
},
useDefaultXhrHeader: false,
headers:{'Content-Type':'application/json'},
api: {
read: 'url given gere'
}
},
fields: [
{
type: 'string',
name: 'id'
},
{
type: 'string',
name: 'name'
},
{
type: 'string',
name: 'desc'
},
{
type: 'string',
name: 'ipAddr'
}
]
});
I have found the issue , You have passed the interval as string in place lo number.
just change to interval: '10000' to inteval: 10000 and your taskrunner will runs fine.
var runner = new Ext.util.TaskRunner(),
updateStore , task;
updateStore = function() {
if (App.app._currentPage == 'devicesform') {
store.load();
} else {
Ext.TaskManager.stop(this);
}
};
task = runner.start({
run: updateStore ,
interval: 1000
});
probably your store.reload is sending again the same params on the request, so with a request that not change nothing changes.

Sencha touch 2.4.1 - localstorage using own ID

I am trying to save data to local storage and I want to use my own ID.
But new id is generated.. and not using my ID.
My model:
Ext.define('mOQOLD.model.ActivityList',{
extend:'Ext.data.Model',
config:{
dProperty : 'uniqueid', // dummy name(not a field)
clientIdProperty : 'ID',
identifier: {
type: 'simple'
},
fields: [
{ name: "ID", type: "auto" },
{ name: "activityID", type: "int" },
{ name: "newRandom", type: "float" },
{ name: "rTime", type: "date", dateFormat: "Y-m-d H:i:s" }
]
}
});
My store:
Ext.define('mOQOLD.store.ActivityListStoreOffline',{
extend:'Ext.data.Store',
requires:["mOQOLD.model.ActivityList",
'Ext.data.proxy.LocalStorage'],
config:{
storeId:"ActivityListStoreOffline",
model:"mOQOLD.model.ActivityList",
grouper: {
groupFn: function(rec) {
var date = rec.get("actDtlStime");
return Ext.Date.format(date, "h a");
}
},
autoLoad:false,
sorters: [
{ property: "actDtlStime", direction: "ASC" }
],
proxy : {
type : 'localstorage',
id : "ActivityListStoreOffline",
model : "mOQOLD.model.ActivityList",
reader: {
type: "json"
}
}
}
})
The result( chrome) :
key : ActivityListStoreOffline-ext-record-19
value:
{"ID":"153",15:13:00","activityID":111,"newRandom":null,"rTime":"2015-05-26 19:31:51","id":"ext-record-19"}
What I expect:
key : ActivityListStoreOffline-153
value:
{"ID":"153",15:13:00","activityID":111,"newRandom":null,"rTime":"2015-05-26 19:31:51"} no id generated!!!
Thanks in advance..
There are two places you can set the ID:
In the model(http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.Model-cfg-idProperty)
and in the reader (http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.data.reader.Reader-cfg-idProperty)
Both places use the "idProperty" attribute. Which defaults to lowercase 'id'.
For example, change your reader to:
proxy : {
type : 'localstorage',
id : "ActivityListStoreOffline",
model : "mOQOLD.model.ActivityList",
reader: {
type: "json",
idProperty: "ID",
}
}

Extjs localstore method set

I am not able to update record in localStorage by id. I get the exception :
Uncaught TypeError: Cannot read property 'type' of undefined WebStorage.js:391Ext.define.getIds WebStorage.js:391Ext.define.update WebStorage.js:190Ext.define.runOperation Batch.js?_dc=1423751003307:251Ext.define.start Batch.js?_dc=1423751003307:178Ext.define.batch Proxy.js?_dc=1423751002203:456Ext.define.sync AbstractStore.js?_dc=1423751002173:810Ext.define.afterEdit AbstractStore.js?_dc=1423751002173:906Ext.define.callStore Model.js?_dc=1423751003310:1814Ext.define.afterEdit Model.js?_dc=1423751003310:1773Ext.define.set Model.js?_dc=1423751003310:1175(anonymous function) Main.js?_dc=1423751002786:26(anonymous function) VM3763:6wrap
My model is simple:
Ext.define('AM.model.Points', {
extend: 'Ext.data.Model',
idProperty: {
name: 'UUID',
type: String,
isUnique: true
},
fields: [
{
name: 'NO',
type: "string"
},
{
name: 'Y',
type: "int"
},
{
name: 'ROW',
type: 'int'
},
{
name: 'SEAT',
type: 'string'
},
{
name: 'PROCEEDED',
type: 'int'
},
{
name: 'X',
type: "int"
},
{
name: "CurrentPlace",
type: "int",
defaultValue: 0
}
],
});
My controller class init function:
init: function(){
// метод getStore контроллера возвращает экземпляр хранилища,
// если он уже создан - или создаёт его
console.log('Main controller init function()');
var changingImage = Ext.create('Ext.Img', {
src: '/is-bin/intershop.static/WFS/EnterpriseOrg-MainChannel-Site/ProductStore/ru_RU/kzch.jpg',
renderTo: Ext.get('canv1')
});
Ext.get('canv1').on('click', function(eventObj, elRef) {
var index = Ext.StoreMgr.lookup("LocalStore").findExact('UUID',AM.util.Utilities.CurrentPlace);
var rec = Ext.StoreMgr.lookup("LocalStore").getAt(index);
console.log('Ext.StoreMgr.lookup("LocalStore") ' + Ext.StoreMgr.lookup("LocalStore"));
console.log('index' + index);
console.log('rec' + rec);
var uuid = rec.get('UUID');
console.log('uuid is: '+uuid);
**rec.set('X', window.event.offsetX);**
});
The logic is that I click on canvas and pass X coordinate of the click to method on click. I retrieve model from store by previously saved id to update it. But I cant update record. What should be done? Version 4.2.1 Thanx in advance.

Store reads, but the store.records.length is always 0

Ext.define('myApp.model.SensorStation', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'name',
type: 'string',
mapping: '#name'
//convert: function (value, record) {
// Ext.Msg.alert(value,record.raw);
// //var nodes = rec.raw.querySelectorAll('');
//}
},
{
name: 'lat',
mapping: '#latitude',
type: 'float'
},
{
name: 'lng',
mapping: '#longitude',
type: 'float'
},
{
name: 'locid',
mapping:'#locid',
type: 'string'
}
]
},
proxy: {
type: 'ajax',
url: 'http://webtrak.bksv.com/mel/configuration',
reader: {
type: 'xml',
record:'locations',
rootProperty: 'nmts'
}
}
});
Ext.define('myApp.store.SensorStationStore', {
extend: 'Ext.data.Store',
requires: ['myApp.model.SensorStation'],
config:{
model: 'myApp.model.SensorStation',
storeId: 'SensorStore'
},
autoLoad: true
});
Ext.define('myApp.controller.SensorStations', {
extend: 'Ext.app.Controller',
requires: ['Ext.MessageBox'],
config: {
refs: {
mapComponent: 'main map'
},
control: {
mapComponent: {
maprender: 'onMaprender'
}
}
},
onMaprender: function (mapComponent, googleMap) {
var store, latlng, marker;
// Use Store name when testing on devices
// Use Store ID when testing in browsers
var sensorStore = Ext.data.StoreManager.get('SensorStore');
if (!sensorStore) {
console.log("Store not found");
Ext.Msg.alert('error', "store not found");
return;
}
//else {
// console.log("Store found");
// Ext.Msg.alert('great', "store found");
// //return;
//}
sensorStore.load({
callback: function (records, operation, success) {
mapComponent.setMapOptions({
center: new google.maps.LatLng(-37.899328, 144.843333)
});
if (success) {
Ext.Msg.alert('success', records);
}
else {
Ext.Msg.alert('error', operation);
}
Ext.Msg.alert('records.count = ' + records.length, 'haha');
}
});
}
});
The records.length is always 0.
Could you please point out where I get wrong?
Also I'd like to know the data structure of the records.
Many thanks
In your model put the proxy: {} inside config:{} and in store put autoload: trueinside config:{}

Resources