Wednesday, May 16, 2012

Elements are not in DOM after Backbone.layoutManager view rendered

I have some editor application with few switchable pages, each of this pages hase it's own action in router. Views are designed using Backbone.LayoutManager. After rendering one of them (editor_publish) i need to draw google map.



When i render this page first time (withing one session), $('.map') selector returns non-empty result and then i can draw map in it. But when I'm trying to render it in second time (i.e. go to another page and then back again to this one), same selector in same code return - 'undefined'. For me this mean that template elements are not in the DOM at the moment i'm trying g to select map container. But why this happens? I can't see difference between first and second pages visit.



I remember something like that was taking place when I re-rendered same Layout manager. But in this code, new LM will be created for each router's action. How this can be solved?



The router:



Editor = Backbone.Router.extend({
immo: {},
lm: {},
nav: [],
pages: [],
routes: {
'editor/basic': 'basic',
'editor/basic/:id': 'basic',
'editor/details': 'details',
'editor/details/:id': 'details',
'editor/photos': 'photos',
'editor/photos/:id': 'photos',
'editor/publish': 'publish',
'editor/publish/:id': 'publish',},
initialize: function(){
var self = this;
if (!_length(self.immo)){
self.immo = new Immo_Object();
}
},

basic: function(id){
var self = this;
self.init(new View_EditorBasic({model: self.immo}));
self.nav.push({caption: '> Next Step', link: 'details'});
self.run(id);
},

details: function(id){
var self = this;
self.init(new View_EditorDetails({model: self.immo}));
self.nav.push({caption: '< Prev Step', link: 'basic'});
self.nav.push({caption: '> Next Step', link: 'photos'});
self.run(id);
},

photos: function(id){
var self = this;
self.init(new View_EditorPhotos({model: self.immo}));
self.nav.push({caption: '< Prev Step', link: 'details'});
self.nav.push({caption: '> Next Step', link: 'publish'});
self.run(id);
},

publish: function(id){
var self = this;
self.init(new View_EditorPublish({model: self.immo}));
self.nav.push({caption: '< Prev Step', link: 'photos'});
self.run(id);
},

init: function(page){
var self = this;
self.nav = [];
self.pages = [
{name: 'basic', caption: 'Basic Infos'},
{name: 'details', caption: 'Details'},
{name: 'photos', caption: 'Photos'},
{name: 'publish', caption: 'Publish'},
];

self.lm = new Backbone.LayoutManager({
template: 'editor',
views:{
'.editor': new View_Editor({
collection: self.pages,
views: {
'.editor_form': page,
'.editor_top_nav, .editor_bottom_nav': new View_EditorNavigation({collection : self.nav})
}})
}
});
},

done: function(self){
if (!self) self=this;
self.compose_navigation();

self.lm.render(function(el){
$('#content').html(el);
$(el).find(".facts dl").columnize();
});
},

run: function(id){
var self = this;
if (id && !self.immo.get('id')){
self.immo.set({id: id});
self.immo.fetch({success: function(){
return self.done(self);
}});
}else{
self.store();
self.done();
}
},

compose_navigation: function(){
var self = this;
_.each(self.nav, function(item){
item.link = 'editor/' + item.link;
if (self.immo.get('id')) item.link += '/' + self.immo.get('id');
});
},

store: function(){
var self = this;
var form = $('.editor_form form').serializeObject();
self.immo.set(form);
return true;
},
});


The view where problem is:



View_EditorPublish = Backbone.View.extend({
template: 'details',

serialize: function(){
return {immo: this.model, details: Immo.details(this.model)};
},

render: function(layout){
return layout(this).render().then(function(el) {
$(el).find(".facts dl").columnize();
console.log($('.map'));
});
},
});




No comments:

Post a Comment