Can I stop a controller from being cleaned up?

Can I stop a controller from being cleaned up when a different route activates? If I’m bouncing back between two views, both being loaded into the same outlet, I would like to keep my controller instances alive. (I’d like to keep the views alive also, but that might not make sense since they’re sharing the same outlet.)

If this isn’t the Ember way of doing things, should I instead persist the data behind the controller, and just load it back into the new controller instance in setupController? (I’m not using Ember Data atm, but I can create something that looks like an Ember Data Store for persisting data even when the controller is cleaned up.)

Are you talking about controllers that are created using {{render 'post'}} or {{render 'post' post}}.

If you use {{render 'post'}}, Ember will always use the same instance of App.PostController, and not clean it up. The second one is a bit more complicated. Our current plan is to “pin” it to its parent context and bring it back to life next time its template is re-rendered, but that’s not done yet.

For now, if you want to store permanent state, you should store it on a singleton controller, and use needs in your other controllers to persist state onto it:

App.PostRoute = Ember.Route.extend({
  model: function() {
    return { id: 1, title: "Hello world" };
  }
});

App.PostController = Ember.ObjectController.extend({
  showingComments: false
});

App.PostInfoController = Ember.ObjectController.extend({
  needs: 'post',

  showComments: function() {
    this.set('controllers.post.showingComments', true);
  },
  
  hideComments: function() {
    this.set('controllers.post.showingComments', false);
  }
});

Your post template might look like this:

<h1>{{title}}</h1>
<label for="showing-comments">Showing comments</label>
{{view Ember.Checkbox id="showing-comments" checkedBinding="showingComments"}}
{{render 'postInfo' post}}

And the postInfo template:

{{#if controllers.post.showingComments}}
  <button {{action hideComments}}>Hide comments</button>
{{else}}
  <button {{action showComments}}>Show comments</button>
{{/if}}

In this case, every time you move to a new post, the postInfo controller will change (for now), but the post controller will remain the same, so you’re free to stash state on there and retrieve it later.

I have made a live JSBin of this approach:

We know that this is just a workaround and hope to have a more automated solution soon :smiley:

That’s great! Thanks for your answer.