简体   繁体   中英

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

Given the following router, with a fairly straight forward routing synatx:

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

I have FoosController , and FooBarController , with corresponding routes for each: FoosRoute and FooBarRoute . Both routes have a model hook that returns a promise, which is obtained from ic.ajax .

When I navigate to /foos , and then navigate to /foos/123/bar , the following sequence happens:

  • FoosRoute#model make XHR request to GET /api/foos
  • Response returned from /api/foos
  • FooBarRoute#model makes an XHR request to GET /api/foos/123
  • Response returned from /api/foos/123

This is great, and my app works fine. Next I naigate directly to /foos/123/bar , the following sequence happens:

  • FoosRoute#model make XHR request to GET /api/foos
  • FooBarRoute#model makes an XHR request to GET /api/foos/123
  • Response returned from /api/foos/123
  • Response returned from /api/foos

The model hooks for both FoosRoute and FooBarRoute fire in quick succession.

The server takes a longer time to return the response from /api/foos than it does for /api/foos/123 , and so they arrive out of order. This puts my app into an incorrect state, and I would like to fix this, by ensuring that the model hook for FooBarRoute is fired only after the promise returned by the model hook for FoosRoute has resolved.

How can I do this?


These JsBins provide a concise demonstration of the problem, forked off the demo put together by @kingpin2k:

Using find . Both models load, but child route loads its model before parent route:

Using fetch . Both models load, and child route correctly waits for parent route to load model, but UI doesn't update:

You need to use fetch as we already discussed, and in your custom find overload you need to return the record, not the results of record.load which is undefined.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM