Ember.js - 切换路由时防止重新渲染 [英] Ember.js - Prevent re-render when switching route

查看:191
本文介绍了Ember.js - 切换路由时防止重新渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简化演示: http://jsfiddle.net/indream/KskXx/

(此演示无法模拟实际环境与我的问题)



演示:悬停在照片将显示标题。

当您点击了照片时,路由已变为媒体,并以 {{linkTo}} 帮助者和灯箱打开。

当灯箱外部点击的位置时,路线通过历史API &灯箱关闭。



我的问题:切换回feed时,模板重新呈现
(你可以通过悬停在图片上的标题来查看它。)

我想停止这个,因为应用程序在重新呈现时滞后,许多照片。



使用 {{linkTo}} 是问题的原因请参阅我的回答



我读过servel相关的问题,如 Ember.js - currentViewBinding并停止在每个视图转换时重新渲染在Emberjs中销毁之前动画化视图

但是提供的方法似乎不适用于RC2,我试图修改 willDestroy 事件,渲染但是它抛出:

未捕获错误:无法对不在的Metamorph执行操作e DOM。

未捕获错误:NotFoundError:DOM异常8

当我切换到另一个路线(即空 nowContent 用于加载其他内容)。并且修改 destroyElement 根本不起作用。



这是我的代码,任何想法来解决我的问题? / p>

  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){
$('# (n);
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();
}
});


解决方案

我已经通过更改 {{linkTo}} {{action}} &编辑位置API的 onUpdateURL 处理程序。



As {{linkTo}} 必须冒泡到路由器,而 {{action}} 不。使用这种方法,URL仍然会更改为Facebook刷新页面,但模板不会重新呈现。



旧模板:


{{/ linkTo}}

新模板:

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

位置处理程序:

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

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

路由器事件:

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

灯箱控制器:

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

注意: HistoryJsLocation 的完整代码请参考 Html4浏览器不支持来自HTML5的history.pushState和history.replaceState历史API方法


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();
  }
});

解决方案

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

这篇关于Ember.js - 切换路由时防止重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆