1

我最近将一些我维护的 Ember 应用程序移植到 RC 8 并遇到了这个问题。

在路由器改头换面之前,我有时会通过 Ember Datafind调用返回的承诺来管理控制流。

例如:

SomeRoute = Ember.Route.extend({
  model: function(params) {
    var resolve = function(model) { return model; };
    var route   = this;
    var reject  = function() { this.transitionTo('someOtherRoute'); };
    return SomeModel.find(params.some_model_id).then(resolve, reject);
  }
  ...
});

通过最近的更改,现在可以通过error操作处理模型回调中创建的错误:

SomeRoute = Ember.Route.extend({
  // note: model callback no longer needed--default suffices
  actions: {
    error: function(reason, transition) {
      // check the reason object to determine how/if to handle this error
      this.transitionTo('someOtherRoute');
    }
  }
  ...
});

我更喜欢后一种方法,因为它使代码更易于阅读并更好地分离关注点。

这在大多数情况下效果很好,但我在使用嵌套路由的应用程序中遇到了问题。我已经包含了一个简化的示例,然后是一个演示该问题的 jsbin。

假设我们要显示Article属于Authors 的 s 并且 URL 看起来像:/authors/:author_slug/articles/:article_slug。当有人试图查看不存在的文章时,我们希望重定向到 Not Found 页面。

model如上所述在回调中管理控制流时,您可以按预期浏览/authors/some_author/articles/some_invalid_slug并重定向到。/authors/some_author/articles/not_found

但是,如果重定向到 Not Found 页面是通过error操作管理的,那么父上下文会在某个时候丢失,最终会出现在/authors/undefined/articles/not_found.

您可以在以下 jsbin 中看到这一点:

http://jsbin.com/eJOXifo/1#/authors/schneier/articles/12345 (重定向到http://jsbin.com/eJOXifo/1#/authors/schneier/articles/not_found

http://jsbin.com/oNaWelo/1#/authors/schneier/articles/12345 (重定向到http://jsbin.com/oNaWelo/1#/authors/undefined/articles/not_found

有谁知道为什么会发生这种情况或如何避免它?

笔记:

  • 我知道这与 Ember Data 没有任何关系。但是,在没有 Ember Data 的情况下实现等价的东西只会使示例变得更加复杂,而无需添加任何内容
  • 有一些小技巧可以让 Ember Data 在 jsbin 中按预期工作:
    • 我正在预加载父模型以避免从任何地方加载它。
    • 我没有做任何特别的事情来为子模型提供数据。该应用程序只是向http://jsbin.com/articles/12345. 这实际上返回一个 200 但无论如何都会炸弹,因为响应是 html。正确返回 404 响应的 API 给出了相同的行为。
    • 我记得不久前阅读了一些服务,这些服务可用于构建虚假 API 响应,以与 jsfiddle 或 jsbin 等服务一起使用。如果有人知道它是什么,请发表评论。
4

1 回答 1

1

您认为父上下文正在丢失的权利。诀窍是从转换中提取上下文并在调用时将其作为参数传递transitionTo。所以:

App.ArticlesArticleRoute = Em.Route.extend({
  actions: {
    error: function(reason, transition) {
      console.log('in error handler');
      this.transitionTo('articles.notFound', transition.resolvedModels.authors);
    }
  }
});

通过此更改,访问 url:

http://jsbin.com/iVOYEvA/2#/authors/schneier/articles/my-fake-article

将重定向到:

http://jsbin.com/iVOYEvA/2#/authors/schneier/articles/not_found

于 2013-08-31T07:07:32.947 回答