When switching from one Ember route to another, I get the following error:
Error: Object in path item_delet could not be found or was destroyed.
In renderTemplate route renderTemplate I do a lot of this:
this.render('item_delete', { into: 'item_parent', outlet: 'item_delete' });
... and have a rational tree of parent / child templates. However, when the pattern, say, "item_delete" is displayed in "routeA", then I click on "routeB" and then return to "routeA", I get an error. I understand that a view object is destroyed when a router exits "routeA" in order to prevent memory leaks. I'm not sure why re-entering the route does not recreate / create / join the view. As a side note, when presenting an error, any of the previously rendered views that receive this error message always has a path name abbreviated by one character, instead of “item_delete”, “item_delet” should be noted.
I use grunt-ember templates to compile Handlebars templates, so posting a JSFiddle is a bit difficult. It's just interesting if anyone can “aim” at this code to point out any obvious reasons why renderTemplate routes or hooks might not be updated / connected / etc. displayed templates. Is there some kind of “activate / deactivate” magic that I can do to prevent the destruction of ideas? (I understand that flies, in the face of intentions, still destroy species, but I’m ready to hear all the options.)
I have an Ember Route map that looks like this:
App.Router.map(function () { this.route('index', { path: '/projects' }); this.resource('items', { path: '/projects/folders' }, function() { this.resource('item', { path: '/:item_id' }, function() { this.route('file_uploads', { path: '/file_upload' }); }); }); });
I have routes defined as follows:
App.IndexRoute = Ember.Route.extend({ redirect: function() { this.transitionTo('items'); } }); App.ItemsIndexRoute = Ember.Route.extend({ model: function() { // Setting up the model } , setupController: function(controller, model) { // Setting up some controllers } , renderTemplate: function() { this.render('index', { into: 'application' , outlet: 'application' , controller: this.controllerFor('items') }); this.render('navbar', { into: 'application' , outlet: 'navbar' , controller: this.controllerFor('currentUser') }); this.render('items', { into: 'index' , outlet: 'index' , controller: this.controllerFor('items') }); this.render('items_toolbar', { into: 'index' , outlet: 'items_toolbar' , controller: this.controllerFor('items') }); this.render('item_rename', { into: 'items_toolbar' , outlet: 'item_rename' , controller: this.controllerFor('items') }); this.render('item_delete', { into: 'items_toolbar' , outlet: 'item_delete' , controller: this.controllerFor('items') }); // ... some more of these... } }); App.ItemRoute = Ember.Route.extend({ model: function (params) { // Building the model for the route } , setupController: function(controller, model) { // Setting up some controllers } , renderTemplate: function() { this.render('index', { into: 'application' , outlet: 'application' , controller: this.controllerFor('items') }); this.render('navbar', { outlet: 'navbar' , into: 'application' , controller: this.controllerFor('application') }); this.render('items', { into: 'index' , outlet: 'index' , controller: this.controllerFor('items') }); this.render('items_toolbar', { into: 'index' , outlet: 'items_toolbar' , controller: this.controllerFor('items') }); this.render('item_rename', { into: 'items_toolbar' , outlet: 'item_rename' , controller: this.controllerFor('items') }); this.render('item_delete', { into: 'items_toolbar' , outlet: 'item_delete' , controller: this.controllerFor('items') }); // ... some more of these... } }); App.ItemFileUploadsRoute = Ember.Route.extend({ model: function() { // Setting up the model } , setupController: function(controller, model) { // Setting up some controllers } , renderTemplate: function() { this.render('file_uploads', { into: 'application' , outlet: 'application' , controller: this.controllerFor('fileUploads') }); this.render('navbar', { into: 'application' , outlet: 'navbar' , controller: this.controllerFor('application') }); this.render('items_toolbar', { into: 'file_uploads' , outlet: 'items_toolbar' , controller: this.controllerFor('fileUploads') }); this.render('item_rename', { into: 'items_toolbar' , outlet: 'item_rename' , controller: this.controllerFor('items') }); this.render('item_delete', { into: 'items_toolbar' , outlet: 'item_delete' , controller: this.controllerFor('items') }); // ... some more of these... } });
I reuse some patterns and their outputs for different routes / resources. For example, the above “items_toolbar” is in the Handlebars template as follows:
<div class="row toolbar"> <div class="col col-lg-6 text-right"> {{outlet submission_options_button}} {{outlet submission_button}} {{outlet create_button}} {{outlet confirm_button}} {{outlet cancel_button}} {{outlet folder_actions}} {{outlet item_rename}} {{outlet item_delete}} </div> </div>
In this template, not all outputs will receive a buffer in them, and in other contexts they will. I do this to avoid unwanted (confusing) conventions in the Handlebars code (and the usual "isVisible" bullshit). I am interested in the fact that this template "wore" their views as necessary; in some cases there can be "create_button" and "cancel_button", and in other cases there can be "cancel_button" and "folder_actions".
Is there any reliable way to make sure that when re-entering a route, any objects that were previously rendered in it, then destroyed, can be reconnected, reinitialized and / or re-mapped?