使用ember-data在ember中使用深度路径的最佳实践

时间:2013-08-14 03:32:06

标签: ember.js coffeescript ember-data

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

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

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

所以这是有效的,但是在尝试了很多方法后我无法完全完成工作的是自动重定向。 我希望一旦加载了类别,使用按类别路由加载的firstObject重定向到类别路由,然后重定向到复合路径,然后重载到复合路径,并在复合路径中加载firstObjevt等。直到最终级别。

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

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

2 个答案:

答案 0 :(得分:3)

  

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

我建议展平这些资源 - 不要让网址结构决定路由嵌套,而是根据模板嵌套资源,并使用path属性指定路由/资源网址。因此,除非你的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);
    });
  }
});

答案 1 :(得分: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中,但是,如果你有更好的解决方案,请提前感谢你让我知道。

相关问题