过渡到 EmberJS 中的加载路由



是否可以在控制器操作上触发加载路由?
例如:

App.PostsController = Ember.ArrayController.extend(
  actions:  
    new:  
      # transitionTo loading
      $.post(...).then (response) ->
        # deactivate loading
)

我想避免为每个控制器添加自定义的"加载"属性,而只使用内置的 LoadRoute。

我在应用程序路由上创建了以下两个操作

startLoading: function () {
  this.set('returnRoute', this.controller.get('currentRouteName'));
  this.intermediateTransitionTo('loading');      
},
endLoading: function () {
  this.intermediateTransitionTo(this.get('returnRoute'));     
}

由于转换是中间的,浏览器历史记录不受影响,didTransitionwillTransition操作不会在路由上触发。 intermediateTransitionTo是公共 API 的一部分,因此应该可以安全使用。

然后我使用这些操作作为

someAction: function() {
  var that = this;
  this.send('startLoading');
  longTask().then(function() {
    that.send('endLoading');
  });            
}

某个路由的model钩返回承诺时,Ember将自动转换为名为App.LoadingRoute的路由。例如:

App.PeopleRoute = Ember.Route.extend({
  model: function(){
      return fetchPeopleFromServer();
  }
});

因此,如果您声明App.LodingRoute和模板(data-template-name="load"),您将在页面中插入该模板的内容,而承诺尚未解决。完成后,将移除加载模板并追加当前路径的模板。

有时您希望将加载模板插入页面的某个区域,默认情况下,它只是附加到最后。在这种情况下,您可以使用出口并覆盖 renderTemplate 来控制此模板的插入位置。例如:

路线

App.LoadingRoute = Ember.Route.extend({
    renderTemplate: function() {            
        this.render('loading', { into: 'application', outlet: 'loading' })        
    }
});

模板

<script type="text/x-handlebars" data-template-name="application">
    <div class="loading">{{outlet "loading"}}</div>
    ...
    {{outlet}}
</script>

您可以使用transitionTo('loading')手动转换为LoadingRoute,就像其他声明的路由一样。例如,在路由操作中触发的长任务中:

someAction: function() {
    var route = this;
    route.transitionTo('loading');
    longTask().then(function() {
        route.transitionTo('index');
    });            
}

这是一个 jsfiddle 在行动中显示了这一点 http://jsfiddle.net/marciojunior/JEqmq/

最新更新