【问题标题】:Make child Route fire model hook only after the promise returned by parent Route has resolved in EmberJs?仅在父路由返回的承诺在 EmberJs 中解决后才使子路由触发模型挂钩?
【发布时间】:2014-03-28 00:57:03
【问题描述】:

给定以下路由器,具有相当直接的路由语法:

App.Router.map(function () {
  this.resource('foos', function(){
    this.resource('foo', { path: '/:foo_id' }, function(){
      this.route('bar');
    });
  });
});

我有FoosControllerFooBarController,每个都有对应的路线:FoosRouteFooBarRoute。 两条路由都有一个 model 钩子,它返回一个从 ic.ajax 获得的承诺。

当我导航到/foos,然后导航到/foos/123/bar 时,会发生以下顺序:

  • FoosRoute#modelGET /api/foos 发出 XHR 请求
  • /api/foos返回的响应
  • FooBarRoute#modelGET /api/foos/123 发出 XHR 请求
  • /api/foos/123返回的响应

这很好,我的应用程序运行良好。接下来我直接导航到/foos/123/bar,发生以下顺序:

  • FoosRoute#modelGET /api/foos 发出 XHR 请求
  • FooBarRoute#modelGET /api/foos/123 发出 XHR 请求
  • /api/foos/123返回的响应
  • /api/foos返回的响应

FoosRouteFooBarRoutemodel 挂钩快速连续触发。

/api/foos/123 相比,服务器返回来自/api/foos 的响应需要更长的时间,因此它们无法按顺序到达。这会使我的应用程序进入不正确的状态,我想通过确保仅在 modelFoosRoute 的钩子返回的承诺已解决后触发 FooBarRoutemodel 钩子来解决此问题。

我该怎么做?


这些 JsBin 提供了问题的简明演示,来自 @kingpin2k 放在一起的演示:

使用find。两个模型都加载了,但是子路由在父路由之前加载它的模型:

使用fetch。两个模型都加载了,子路由正确等待父路由加载模型,但是 UI 没有更新:

【问题讨论】:

  • 类似RSVP.all([promise1,promise2]).then(function(){ /* this runs only when both promises resolved */ }) ?
  • @BenjaminGruenbaum 有没有一种方法可以从子 Routemodel 钩子中获得对父 Routemodel 钩子的承诺的引用?如果是这样,这可能会奏效。
  • 我有点困惑,这就是 Ember 的构建方式,直到父路由的模型被解析后,子路由的模型钩子才会触发。您确定父路线正在返回承诺吗?这是一个示例,其中子路由依赖于父路由模型emberjs.jsbin.com/OxIDiVU/333#/colors/1,并且在解析父路由的模型之前不会发生模型挂钩。
  • 您是否会添加您的模型挂钩并提及您可能正在使用的任何客户端数据库
  • @kingpin2k 感谢 jsbin。是的 - 我的应用程序中的所有路由都在其model 挂钩中返回承诺。我在model 钩子中使用ember-model,在它的适配器中,我使用ic-ajax(这是承诺的起源)

标签: javascript ajax ember.js promise ember-router


【解决方案1】:

您需要使用我们已经讨论过的fetch,并且在您的自定义find 重载中您需要返回记录,而不是未定义的record.load 的结果。

return App.AppModel.fetch(1);

App.AppModel.adapter = Ember.Adapter.create({
    find: function(record, id) {
        //instead of jQuery.ajax, use ic.ajax as suggested by stefanpenner
        //See: https://github.com/emberjs/ember.js/issues/4442#issuecomment-36207354
        var req = ic.ajax.raw({
            type: 'GET',
            url: App.apiUrl+'/appmodels/'+id,
            contentType: 'application/json',
            dataType: 'json',
            processData: false
        });
        return req.then(function resolve(result) {
          console.log('AppModel adapter find resolve', result.response);

          record.load(id, result.response);
          return record;
        });
    }
});

http://jsbin.com/cukuciva/1/edit

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 2022-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多