mark.haylock
30 May 2011, 1:27 PM
Sencha Touch version tested:
1.1.0
Platform tested against:
iOS 4
Android 2.1
Description:
New records are duplicated in a store after .sync() is called, when using an AjaxProxy.
Test Case:
// models/contact.js
app.models.Contact = new Ext.regModel('Contact', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'first_name', type: 'string' },
{ name: 'last_name', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'phone', type: 'string' }
],
validations: [
{ type: 'presence', field: 'first_name', message: 'none' },
{ type: 'presence', field: 'last_name', message: 'none' },
{ type: 'email', field: 'email', message: 'Please enter a valid e-mail address.' },
{ type: 'phone', field: 'phone', message: 'Please enter a valid phone number.'}
],
proxy: {
type: 'ajax',
url: 'contacts.xml',
reader: {
type: 'xml',
record: 'contact'
},
writer: {
type: 'xml',
record: 'contact'
}
}
});
Ext.regStore('contacts', {
autoLoad: true,
model: 'Contact',
sorters: ['last_name'],
sortOnLoad: true,
getGroupString : function(record) {
return (record.get('last_name') || '#')[0].toUpperCase();
},
});
// in views/contacts/list.js
app.views.ContactsList = Ext.extend(Ext.Panel, {
title: 'Contacts',
layout: 'fit',
store: 'contacts',
initComponent: function () {
this.list = new Ext.List({
xtype: 'list',
id: 'contactslist',
grouped: true,
indexBar: true,
store: this.store,
itemTpl: '{first_name} <strong>{last_name}</strong>'
});
this.items = [this.list];
app.views.ContactsList.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('contacts/list', app.views.ContactsList);
// in controller:
var contact = Ext.ModelMgr.create(this.form.getValues(), 'Contact');
var store = Ext.getStore('contacts');
store.add(contact);
store.sync(); // Duplicate appears in views list once .sync() asynchronously completes.
Steps to reproduce the problem:
Attach a store (backed by an AjaxProxy) to a list
Add a new (unsaved) record to the same store
Call .sync() on store
The result that was expected:
List should reflect one new item in the store
The result that occurs instead:
List shows the new item twice
Debugging already done:
Determined that the record returned from the server is never matched against the existing record in the store - because the internalId doesn't match.
Possible fix:
Please see this commit on github (https://github.com/resolve/sencha-contacts-demo/commit/5e6c683fbfb6023efda40c4a60a75b100b020f23) for my change to AjaxProxy.js which fixes this for me.
Note that the list isn't sorted properly within each group after my fix, but that might be the fault of the way I'm sorting things at the moment.
1.1.0
Platform tested against:
iOS 4
Android 2.1
Description:
New records are duplicated in a store after .sync() is called, when using an AjaxProxy.
Test Case:
// models/contact.js
app.models.Contact = new Ext.regModel('Contact', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'first_name', type: 'string' },
{ name: 'last_name', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'phone', type: 'string' }
],
validations: [
{ type: 'presence', field: 'first_name', message: 'none' },
{ type: 'presence', field: 'last_name', message: 'none' },
{ type: 'email', field: 'email', message: 'Please enter a valid e-mail address.' },
{ type: 'phone', field: 'phone', message: 'Please enter a valid phone number.'}
],
proxy: {
type: 'ajax',
url: 'contacts.xml',
reader: {
type: 'xml',
record: 'contact'
},
writer: {
type: 'xml',
record: 'contact'
}
}
});
Ext.regStore('contacts', {
autoLoad: true,
model: 'Contact',
sorters: ['last_name'],
sortOnLoad: true,
getGroupString : function(record) {
return (record.get('last_name') || '#')[0].toUpperCase();
},
});
// in views/contacts/list.js
app.views.ContactsList = Ext.extend(Ext.Panel, {
title: 'Contacts',
layout: 'fit',
store: 'contacts',
initComponent: function () {
this.list = new Ext.List({
xtype: 'list',
id: 'contactslist',
grouped: true,
indexBar: true,
store: this.store,
itemTpl: '{first_name} <strong>{last_name}</strong>'
});
this.items = [this.list];
app.views.ContactsList.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('contacts/list', app.views.ContactsList);
// in controller:
var contact = Ext.ModelMgr.create(this.form.getValues(), 'Contact');
var store = Ext.getStore('contacts');
store.add(contact);
store.sync(); // Duplicate appears in views list once .sync() asynchronously completes.
Steps to reproduce the problem:
Attach a store (backed by an AjaxProxy) to a list
Add a new (unsaved) record to the same store
Call .sync() on store
The result that was expected:
List should reflect one new item in the store
The result that occurs instead:
List shows the new item twice
Debugging already done:
Determined that the record returned from the server is never matched against the existing record in the store - because the internalId doesn't match.
Possible fix:
Please see this commit on github (https://github.com/resolve/sencha-contacts-demo/commit/5e6c683fbfb6023efda40c4a60a75b100b020f23) for my change to AjaxProxy.js which fixes this for me.
Note that the list isn't sorted properly within each group after my fix, but that might be the fault of the way I'm sorting things at the moment.