In ExtJS 6.2, having a store with some default data, how can I overwrite the default data with data from a database?
Example:
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone'],
data: [{
'name': 'Lisa',
"email": "lisa@simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart@simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home@simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge@simpsons.com",
"phone": "555-222-1254"
}],
//idProperty: 'name',
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total'
}
}
});
Then, in my database Lisa actually has phone number "555-111-4321", so when I call store.load() it will overwrite Lisa's phone number with "555-111-4321".
Please see fiddle: https://fiddle.sencha.com/#view/editor&fiddle/3h05
There could be a more elegant solution, something built-in ExtJS, but manually checking for existing rows and deleting these from the original store, before adding the new one does work. Add these lines to the end of your fiddle code:
newStore = Ext.clone(store);
newStore.load({addRecords: true,
callback: function (records, operation, success) {
if (!success) return;
Ext.Array.each(records, function(record) {
const existing = store.findRecord('name', record.get('name'));
if (existing != null) {
store.remove(existing);
}
store.add(record);
});
}
});
I solved this issue creating overrides:
Ext.define(null, {
override: 'Ext.data.ProxyStore',
privates: {
createImplicitModel(fields) {
//const me = this;
const modelCfg = {
extend : this.implicitModel,
statics : { defaultProxy: 'memory' }
};
if (fields) modelCfg.fields = fields;
// Add
if (this.idProperty) modelCfg.idProperty = this.idProperty;
const model = Ext.define(null, modelCfg);
this.setModel(model);
const proxy = this.getProxy();
if (proxy) {
model.setProxy(proxy);
} else {
this.setProxy(model.getProxy());
}
}
},
load(options) {
if (typeof options === 'function') {
options = { callback: options };
} else {
options = options ? Ext.Object.chain(options) : {};
options = {...options, ...this.loadOptions};
}
this.pendingLoadOptions = options;
if (this.getAsynchronousLoad()) {
if (!this.loadTimer) {
this.loadTimer = Ext.asap(this.flushLoad, this);
}
} else {
this.flushLoad();
}
return this;
}
});
var store = Ext.create('Ext.data.Store', {
fields: ['ids','name','email', 'phone'
],
autoLoad: true,
loadOptions: {addRecords: true},
idProperty: 'name',
data: [{
'ids':1,
'name': 'Lisa',
"email": "lisa@simpsons.com",
"phone": "555-111-1224"
}, {
'ids':2,
'name': 'Homer',
"email": "home@simpsons.com",
"phone": "555-222-1244"
}],
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total'
}
}
});
Ext.create('Ext.grid.Grid', {
title: 'Simpsons',
store: store,
columns: [{
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Email',
dataIndex: 'email',
width: 250
}, {
text: 'Phone',
dataIndex: 'phone',
width: 120
}],
height: 200,
layout: 'fit',
fullscreen: true,
renderTo: Ext.getBody()
});
// store.load();
//store.load({addRecords: true}); // Keeps Homer but duplicates data
Please see fiddle: https://fiddle.sencha.com/#fiddle/3h2v&view/editor
This allows you to use any field and field type as ID, it works with autoload on.
If you only want to use the id field as ID and it being numeric, then this should work: https://fiddle.sencha.com/#fiddle/3h15&view/editor