Dear All,
I encountered a problem with getting right values from the form's input fields in the following scenario:
I need to recreate the view object every time I'm switching to it - this is because the view displays different set of fields depending on the contents of the associated data record (the record contains contact data - so you can imagine - sometimes there is only name, surname and email, and sometimes there is a dozen of phone numbers, a few addresses and so on) . So I decided to dynamically create view's content inside the initialize() method. This is the code for the view object (simplified, contains only one simple, dynamically added text field)
Code:
Ext.define('MyApp.view.MyView', {
extend: 'Ext.form.Panel',
xtype: 'myview',
constructor: function(config) {
this.record = config.record;
},
initialize: function() {
this.callParent(arguments);
var fieldset = Ext.create('Ext.form.FieldSet', {});
fieldset.add(Ext.create('Ext.field.Text', { name: 'test' }));
/* ... and some other stuff depending on the contents of this.record */
}
});
This is how I switch to the view in the controller:
Code:
Ext.Viewport.getLayout().setAnimation({ type: 'slide', direction: 'left', duration: 150 });
Ext.Viewport.setActiveItem(Ext.create('MyApp.view.MyView', { record: theRecord }));
The view gets displayed, I fill up the field (let's assume I have entered 'YUP!') and tap on the button to examine contents of the view and to go back to the previous view:
Code:
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
refs: [{
ref: 'test',
selector: 'textfield[name=test]'
}],
/* init() function is pretty standard, simple handler for a toolbar button, no problems with that
let's assume the handler is called onMyButtonTap
*/
onMyButtonTap: function() {
var s = this.getTest().getValue();
alert(s);
Ext.Viewport.getLayout().setAnimation({ type: 'slide', direction: 'left', duration: 150 });
Ext.Viewport.setActiveItem(Ext.create('MyApp.view.MyPreviousView', { }));
}
});
So far so good, alert says exactly what I have entered - in this case "YUP!". So far, no surprises.
Then I repeat switching to the MyApp.view.MyView, the input field is empty (after all, I have created a new instance of the view object...), so I enter, let's say, "BLEEEE", and tap on the button. The alert gets displayed again and it says - surprise - "YUP!". And this is the part I don't understand...
And one more detail: Because of the fact that I don't reuse already instantiated view objects and rather recreate them every time, I need to destroy them as well when they got hidden, otherwise the DOM grows and grows and grows. This is how I do it:
Code:
Ext.Viewport.on('activeitemchange', function(viewport, newCard, oldCard) {
if (oldCard) {
Ext.defer(Ext.Viewport.remove, 1000, Ext.Viewport, [oldCard, true]);
}
});
(I use deferred call because the event is fired just before the active item is changed, not after that)
I don't know if this is the right way of doing it (I receive some errors about non-existing dom properties, but I think it may be connected to the fact that Touch 2.0 is still in developer preview phase), but it seems that this code doesn't hurt at least (well, when I comment it out, the main issue still is there). But it may be also that when I don't use this "cleaning up" code I have duplicates of view objects which make the whole thing not working, and when I use it, it messes up the things elsewhere. That's why I mention that here.
Back to the problem - it seems to be connected to the fact that instead of reusing already instantiated and initialized view objects I rather recreate them every time I need them, and destroy them when they just got hidden.
This is what I just noticed: getter functions created automagically by the Touch in the controller once you add some component queries to the refs: [] collection seem to be attached always to the first instance of the view ever created.
What do you think?
Michal