Ember.js - Prevent re-render when switching route

梦想与她 提交于 2020-01-01 19:19:07

问题


Simplified demo: http://jsfiddle.net/indream/KskXx/
(this demo cannot simulate actual environment with my problem)

For the demo: Hover on photos will show you the caption.
When you clicked a photo, route changed to 'media' with {{linkTo}} helper & lightbox opened.
When clicked place outside lightbox, route changed back to 'feed' by history API & lightbox closed.

My question: Template re-rendered when switch back to 'feed'.
(You can check it by hover on photos as caption lost after that.)
I want to stop this as the app lagged during re-render if there're lots of photos.

Using {{linkTo}} is the reason of problem, please refer to my answer

I've read servel releated question like Ember.js - currentViewBinding and stop re-rendering on every view transition and Animating views before destruction in Emberjs.
But the methods provided seems not work for RC2, I've tried to modify willDestroy event, it works for not re-render but it throwed:
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM.
Uncaught Error: NotFoundError: DOM Exception 8
when I switched to another route (i.e. empty nowContent for loading other content). And modify destroyElement isn't work at all.

Here's my code, any ideas to solve my problem?

App.MainView = Ember.View.extend({
  templateName:'main',
  willDestroy: function() {
    if (App.get('destroyCurrentView')){
      this._super();
    }
  }
})
App.PageController = Ember.Controller.extend({
  lightboxClose:function(e){
    if(!e||e.target==e.currentTarget){
      $('#lightbox').hide();
      $('body').removeClass('noscroll');
      history.back();

      App.set('destroyCurrentView',false);
      setTimeout(function(){
        App.set('destroyCurrentView',true);
      }, 500);
    }
});
App.MediaRoute = App.mainRoute.extend({
  enter:function(){
    App.set('destroyCurrentView',false);
    this._super();
  }
});

回答1:


I've solved this by changing {{linkTo}} to {{action}} & editing the onUpdateURL handler of location API.

As {{linkTo}} must bubble up to Router while {{action}} not. With this approach, URL still changes for page refresh like Facebook but template will not re-render.

Old Template:

{{#linkTo media feed.id}}
<img src="{{unbound feed.images.low_resolution.url}}" />
{{/linkTo}}

New Template:

<img {{action transitionToMedia feed.id}} src="{{unbound feed.images.low_resolution.url}}" />

Location Handler:

Ember.HistoryJsLocation = Ember.Object.extend({
  onUpdateURL: function(callback) {
    ...
    Ember.$(window).bind('popstate.ember-location-'+guid, function(e) {
      if(window.suppressUpdateURL)return;
      ...
    });
  }
});

Ember.Location.registerImplementation('historyJs', Ember.HistoryJsLocation);

Router Event:

App.mainRoute = Em.Route.extend({
  events: {
    transitionToMedia: function (id) {
      window.suppressUpdateURL = true;
      History.pushState(null, null, '/m/'+id);
      App.pageController.lightbox(id);
    }
  }
});

Lightbox Controller:

Folo.PageController = Em.Controller.extend({
  lightboxClose: function(e){
    ...
    History.back();
    window.suppressUpdateURL = false;
  }
});

Note: Complete code for HistoryJsLocation please refer to Html4 browsers does not support history.pushState and history.replaceState methods of History API from HTML5



来源:https://stackoverflow.com/questions/15990860/ember-js-prevent-re-render-when-switching-route

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!