PDA

View Full Version : removeAll causing uncaught TypeError



bobbaluba
1 Aug 2011, 4:32 AM
I'm having some trouble deleting all the items within a panel that is not currently visible.

I have a tabpanel with three different lists (Ext.Panel subclasses), which contains several Ext.containers, when i refresh the list, i call removeAll on all three panels, and then add new containers to each of them.
So far everything works great, the list I am currently viewing gets updated, but when i try to switch to one of the other tabs, i get this error:

Uncaught TypeError: Cannot read property 'style' of undefined


if I comment out removeAll(true), everything works perfectly, except no items are deleted of course, causing the lists to contain the data twice.

Any ideas? My deadline was yesterday, so any help is very much appreciated.

EDIT: I've posted the problem in code in post 5

mitchellsimoens
1 Aug 2011, 7:35 AM
It sounds like things aren't getting destroyed properly. I'm assuming you tried removeAll without the true, it will default to the autoDestroy property on each item.

Can I see some code to see what's going on?

bobbaluba
1 Aug 2011, 8:31 AM
Thanks for the reply.
I'm using removeAll with true.
My code is quite long, so I won't post everything:

The lists

app.views.ProjectList = Ext.extend(Ext.Container, {
model:[],
scroll:'vertical',
styleHtmlContent:true,
initComponent: function(){
app.views.ProjectList.superclass.initComponent.call(this);
},
filter: function(project){
return false;
},
update: function(){
this.removeAll(true);
for(var i=0; i< this.model.length; i++){
var projectView = new app.views.ProjectView({
model: this.model[i],
});
if(!this.filter(this.model[i]))this.add(projectView);
}
this.doLayout();
},
setModel: function(model){
this.model=model;
this.update();
}
});

The internal containers

app.views.ProjectView = Ext.extend(Ext.Container, {
componentCls: 'projectListEl',
styleHtmlContent: false,
height: 100,
width: '100%',
padding:'5px',
layout: {type: 'hbox'},
initComponent: function() {
app.views.ProjectView.superclass.initComponent.call(this);
this.model.addObserver(this);
this.cls = 'projectListEl';

//create icons field
var iconsField = new Ext.Container({
layout: {type: 'vbox'},
align: 'center',
width: '50',
height: '100%',
// cls: 'iconsField',
});
iconsField.add([
loadedIcon = new ProjectIcon({
model: this.model,
prop: 'loaded',
}),
dirtyIcon = new ProjectIcon({
model: this.model,
prop: 'dirty',
}),
]);

var mainField = new Ext.Container({ // mainField (description and buttons)
layout: {type: 'vbox'},
flex: 1,
height: '90%',
items: [
{// project description text
html: '<h4 class="description">' + this.model.getDescription() +'</h4>',
width: '100%',
layout:'fit',
flex:1
},
{ // buttonsline
flex:1,
layout: {type: 'hbox'},
cls: 'projectsListButtons',
width:'100%',
items: [
{xtype: 'Actionsbutton', model: this.model},
{xtype: 'spacer', flex: 5},
{xtype: 'Detailsbutton', model: this.model},
{xtype: 'spacer', flex: 5},
],
},
],
});


this.add([
iconsField,
mainField
]);
if (this.model.isFavorite()) this.cls = 'projectListFavorite';

this.doLayout();

},
changeBackgroundColor: function() {
if (this.model.isFavorite()) {
this.addCls('projectListFavorite');
}
else {
this.removeCls('projectListFavorite');
}
},
propertyChanged: function(){
this.changeBackgroundColor();
},
destroy: function(){
this.model.removeObserver(this);
app.views.ProjectView.superclass.destroy.call(this);
}
});

TabPanel:

app.views.ProjectsLists = Ext.extend(Ext.TabPanel, {
model:[],
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
layout: 'card',
scroll: 'vertical',
cardSwitchAnimation: {
type: 'slide',
},

dockedItems: [{
xtype: 'toolbar',
title: 'Projects',
items: [
{
xtype: 'button',
text: 'Log out',
ui:'back',
handler: function(){app.controllers.login.logout();}
},
{xtype: 'spacer'},
{
xtype: 'button',
iconCls:'refresh', iconMask:true, ui:'plain',
handler: data.refreshProjects
}
],
}],

items: [
app.views.projectListAll,
app.views.projectListFavorites,
app.views.projectListOffline,
],

updateWithProjects: function(projects) { // TODO dårlig navn. kalles i data
for(var i=0; i< this.model.length; i++){
this.model[i].removeObserver(this);
}
this.model = projects;
for(var i=0; i< this.model.length; i++){
this.model[i].addObserver(this);
}

app.views.projectListAll.setModel(projects);
app.views.projectListFavorites.setModel(projects);
app.views.projectListOffline.setModel(projects);
},

propertyChanged: function(property, project){
if(property == "loaded"){
app.views.projectListOffline.update();
}
else if(property == "favorite"){
app.views.projectListFavorites.update();
}
}
});

EDIT: Misread your post. Yes, I've tried removeAll without the true, which causes the exact same behaviour, I've also tried with false, which causes all the elements in the list to appear two times.

bobbaluba
1 Aug 2011, 11:39 PM
Here's my call stack if it you're interested:

Uncaught TypeError: Cannot read property 'style' of undefined sencha-touch-debug.js:12136
El.addMethods.setSize sencha-touch-debug.js:12136
Ext.layout.ComponentLayout.Ext.extend.setElementSize sencha-touch-debug.js:28966
Ext.layout.ComponentLayout.Ext.extend.setTargetSize sencha-touch-debug.js:28983
Ext.layout.AutoComponentLayout.Ext.extend.onLayout sencha-touch-debug.js:29024
Ext.layout.Layout.Ext.extend.layout sencha-touch-debug.js:28818
Ext.lib.Component.Ext.extend.doComponentLayout sencha-touch-debug.js:19931
Ext.lib.Container.Ext.extend.show sencha-touch-debug.js:20989
Ext.layout.CardLayout.Ext.extend.setActiveItem sencha-touch-debug.js:29712
Ext.TabBar.Ext.extend.onTabTap sencha-touch-debug.js:24143
Ext.TabBar.Ext.extend.onTouchStart sencha-touch-debug.js:24117
anonymous:5
(anonymous function) sencha-touch-debug.js:4428
Ext.gesture.Gesture.Ext.extend.fire sencha-touch-debug.js:18588
Ext.gesture.Touch.Ext.extend.onTouchStart sencha-touch-debug.js:18658
Ext.gesture.Manager.Ext.AbstractManager.handleTarget sencha-touch-debug.js:18348
Ext.gesture.Manager.Ext.AbstractManager.handleTargets sencha-touch-debug.js:18324
Ext.gesture.Manager.Ext.AbstractManager.onTouchStart sencha-touch-debug.js:18205
(anonymous function) sencha-touch-debug.js:3421

I don't know enough about senchas internals to make sense of what's happening, but maybe some of you guys do?

EDIT: Some progress...
I commented out pieces of my code to see if something else was causing the component destruction to fail. Finally, I managed to get rid of the error. The lines that did the difference, was a height and widht variable of ProjectView (the containers the list is composed of).

I will try to create a more stripped down version of the problem so you won't have to read through all of my code.

bobbaluba
2 Aug 2011, 4:45 AM
Ok, I'm still struggling with this, but I've reduced the problem to these independent 50 lines of code:

SingleRow = Ext.extend(Ext.Container, {
height: 100,
width: '100%',
items:{html:'boo'},
});

//the list
List = Ext.extend(Ext.Container, {
updateWithProjects: function(){
this.removeAll();
for(var i=0; i< 3; i++){
this.add(new SingleRow());
}
this.doLayout();
}
});
Ext.reg('List', List);

listAll = new List({title:'all'});
listFavorites = new List({title:'favorites'});

Lists = Ext.extend(Ext.TabPanel, {
layout: 'card',
dockedItems: [{
xtype: 'button',
text: 'refresh',
handler: function(){lists.updateWithProjects();}
}],
items: [
listAll,
listFavorites,
],
updateWithProjects: function() {
listAll.updateWithProjects();
listFavorites.updateWithProjects();
}
});

lists = new Lists();

var App = new Ext.Application({
name: 'theapp',
launch: function () {
viewport = new Ext.Panel({
fullscreen: true,
layout: 'card',
items: [
lists
]
});
lists.updateWithProjects(); //placing the line here causes an error
},
});

bobbaluba
2 Aug 2011, 5:19 AM
Ok. I gave up and just added the width and height properties to a css class instead. stupid sencha touch. :(