Prevent re-rendering of template when transitioning to a route


#1

I have a route and an associated template. The template provides a skeleton div into which I manually render content instead of using data binding (using D3 in one case).

Is there a way to configure a route/template to not re-render the template from scratch if it was previously rendered, but instead simply display the last content?


Prevent destroying component on route change
#2

I believe that is the behavior by default as long as you’re transitioning to the same route, but with a new model/context. (I do this often to create animated D3 Charts…I’m assuming that’s what you’re after). I think this has been the case since about RC1.

There are reasons why that particular div may be inadvertently re-rendered; but that depends on what your templates look like. Care to share more specifics? (I might be able to have better insight).


#3

I don’t think I was clear in my original problem statement. Let me try again:

AFAIK, templates + routing work like this: when entering a route, HTML elements for the associated template are generated and appended to the DOM (-> render). When transitioning to a different route, the original route’s elements are removed from the DOM and new nodes resulting from the template from the new route are inserted into the DOM.

This means that when you go back to the first route, it’s associated DOM nodes are re-generated.

But this is not what I want. Instead, if a route caused elements to be generated + inserted into the DOM, I do not want that to happen again when I go back to that route, but rather simply show the elements that were previously generated.

Here is a simple example that illustrates the problem. I have a template like this:

<script type="text/x-handlebars" id="debugger">
  <div id="debuggerContainer">
    <iframe id="debuggerFrame" src="http://localhost:8085">        
    </iframe>
  </div>
</script>

And this route: <li>{{#link-to "debugger"}}Debugger{{/link-to}}</li>

Every time I go to the route, the iframe is reloaded. But for various reasons this should not happen.

So what I’m really after is this:

  • first time in route, create elements and append to DOM
  • when navigate to another route, hide instead of remove elements of previous route
  • going back to original route: show its nodes, don’t recreate.

Is there a recommended way to do this in Ember?


#4

Ahh…that’s an interesting question. You could manually append a pre-generated view object in Javascript to a view class that you create. Something like:

Original Template:

<script type="text/x-handlebars" id="debugger">
  {{view App.DebuggerContainerView}}
</script>

Then, in Javascript:

(function() {      

var debuggerFrame = Ember.View.create({
  id : "debuggerFrame",
  tagName : "iframe",
  src : "http://localhost:8085"
});
    
App.DebuggerContainerView = Ember.ContainerView.extend({
  didInsertElement : function() {
    this.pushObject( debuggerFrame );
  }
});

})();

The DebuggerContainerView will be regenerated every time the route is re-entered; however, it will continue to use the same instance of the debuggerFrame as it’s only child. That’s the theory at least. Again, haven’t actually tried this.


#5

Hi, I’m interested in a solution for this as well. There are some views that are too expensive to be re-rendered every time and it kills the UX. I’ve found workarounds and suggestions that, unfortunately, don’t work anymore.

I was thinking in something like this to be included in ember itself:

App.DebuggerView = Ember.View.extend({
    destroyMode: 'hide' // by default 'remove'
});

#6

I haven’t actually tried this, but I stumbled on http://stackoverflow.com/a/11518047