在EmberJs中,只有在父路由返回的承诺被解析后,才让子路由触发模型钩子

Make child Route fire model hook only after the promise returned by parent Route has resolved in EmberJs?

本文关键字:路由 模型 承诺 EmberJs 返回      更新时间:2023-09-26

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

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
  • 返回的响应

model的钩子为FoosRouteFooBarRoute快速连续射击。

服务器从/api/foos返回响应的时间比从/api/foos/123返回响应的时间长,因此它们是乱序到达的。这使我的应用程序进入一个不正确的状态,我想通过确保FooBarRoutemodel钩子只有在FoosRoutemodel钩子返回的承诺解决后才被触发来解决这个问题。

我该怎么做?


这些jsbin提供了问题的简明演示,从@kingpin2k:

的演示中派生出来。

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

  • http://jsbin.com/topot/3/edit?html, js、控制台、输出

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

  • http://jsbin.com/topot/4/edit?html, js、控制台、输出

您需要使用我们已经讨论过的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