1

我有一个看起来像这样的路由器:

App.Router.map ->
  @resource 'categories', ->
    @resource 'category', path: ':category_id', ->
      @resource 'composites', ->
        @resource 'composite', path: 'composite_id, ->
          @resource 'questions', ->
            #...

所有复数路由都有一个模型挂钩,根据父级加载所有模型(加载所有类别的根资源除外)。像复合模型钩子会做类似的事情App.Composite.find category_id: @modelFor('category').get('id')

所以这是可行的,但是在尝试了多种方法后我无法完全完美地工作是自动重定向。我希望一旦加载了类别,就使用类别路由加载的 firstObject 重定向到类别路由,然后重定向到复合路由,然后重定向到复合路由中加载了 firstObjevt 的复合路由,等等。直到最终水平。

我使用重定向使其部分工作,firstObjectObserver,......但我经常遇到无限重定向的问题,或者在尝试使用第一个模型重定向到下一个路由之前没有加载模型,......

这样做的最佳做法是什么?我是否应该以另一种方式重写我的路由器(我希望能够为每个级别提供一个 URL,即使最终它会自动重定向到最后一个级别,但模型可以更改)?在重定向之前我应该​​如何等待多个路由模型加载?

4

2 回答 2

3

这样做的最佳做法是什么?我应该以另一种方式重写我的路由器吗

我建议展平这些资源 - 不要让 url 结构决定路由嵌套,而是根据您的模板嵌套资源并使用 path 属性来指定路由/资源 url。因此,除非你的 UI 真的有一个非常嵌套的包含类别、组合和问题的主从模板,否则这样的事情会更有意义:

App.Router.map ->
  @resource 'categories'
  @resource 'category', path: '/categories/:category_id', ->
    @resource 'composites'
    @resource 'composite', path: 'composites/:composite_id, ->
      @resource 'questions'
        #...

在重定向之前我应该​​如何等待多个路由模型加载?

无论哪种方式,重定向都应该像这样工作:

App.CategoriesRoute = Ember.Route.extend({
  model: function() {
    return App.Category.find({});
  }
});
App.CategoriesIndexRoute = Ember.Route.extend({
  redirect: function() {
    var category = this.modelFor('categories').get('firstObject');
    this.transitionTo('category', category);
  }
});

这种方法不起作用吗?也许这会奏效:

App.CategoriesIndexRoute = Ember.Route.extend({
  redirect: function() {
    return App.Category.find({}).then(function(results) {
      var category = results.get('firstObject');
      return this.transitionTo('category', category);
    });
  }
});
于 2013-08-14T04:59:16.363 回答
2

好的,我想我明白了。我必须在重定向中返回一个承诺来为复数路线做伎俩:

App.CategoriesIndexRoute = Em.Route.extend
  redirect: (model, transition) ->
    models = @modelFor('categories')
    if (model = models.get 'firstObject')
      @transitionTo 'category', model
    else
      promise = Em.Deferred.create()
      observer = =>
        return unless (model = models.get 'firstObject')
        models.removeObserver 'firstObject', observer
        promise.resolve(@transitionTo 'category', model)
      models.addObserver 'firstObject', observer
      promise

这样就可以了。我很确定有一个更好的解决方案,我现在已经把它放在一个 mixin 中,但是如果你有更好的解决方案,请提前让我知道。

于 2013-08-14T08:35:08.207 回答