0

我正在尝试使用 Ember 模型做一些基本的事情,但我遇到了一些带有承诺的奇怪行为。不确定我是否非常了解它应该如何工作。

所以,我有这条路线:

App.ProfilesIndexRoute = Ember.Route.extend {

  redirect: ->
    App.Profile.fetch().then (profiles) ->
      console.log profiles.get('length')
      @transitionTo 'profile', profiles.get('firstObject')

}

我只是希望人们在访问时被重定向到/profiles/123(= 第一个配置文件)/profiles

这是配置文件适配器:

App.Profile.adapter = Ember.Adapter.create {

  findAll: (klass, records) ->
    $.ajax('/api/users/' + $.cookie('user_id'), {
      type: 'get'
      headers: {
        'Content-Type': 'application/json'
        'Authentication-Token': $.cookie('token')
      }
      dataType: 'json'
    }).then (res) ->
      profiles = []
      // some stuff done here
      records.load klass, profiles

}

当我转到 时/profiles,这是我在控制台中看到的内容:

0
Transitioned into 'profiles.index'
XHR finished loading: "http://localhost/api/users/456". 

0是 的结果console.log profiles.get('length')。似乎它是在 AJAX 调用有机会完成之前调用的。我的控制台中应该有这样的东西:

Transitioned into 'profiles.index'
XHR finished loading: "http://localhost/api/users/456". 
5

我在这里做错了什么?这里有人建议我使用fetchfind但它似乎并没有解决我的问题,因为事情没有按正确的顺序执行。

谢谢!

4

3 回答 3

1

afterModel您应该从钩子重定向到不同的路线:

App.ProfilesIndexRoute = Ember.Route.extend {

  model: ->
    App.Profile.fetch()

  afterModel: (profiles, transition) =>
    @transitionTo 'profile', profiles.get('firstObject')

}

此外,由于您正在使用@,您应该使用粗箭头=>来正确引用this.

希望能帮助到你。

于 2013-08-21T19:52:33.193 回答
1

我认为您覆盖适配器的方式是错误的:

您正在使用延迟的 jquery ajax。但是我认为您需要将该调用包装在 RSVP 中。因为 ember 使用 RSVP 来处理承诺。

看看那个实现

App.Profile.adapter = Ember.Adapter.create({
    ajaxSettings: function(url, method) {
        return {
            headers: {
                'Content-Type': 'application/json'
                'Authentication-Token': $.cookie('token')
            },
            dataType: "json"
        };
    },
    findAll: function(klass, records) {
        var url = '/api/users/' + $.cookie('user_id'),
        self = this;

        return this.ajax(url).then(function(data) {
            self.didFindAll(klass, records, data);
            return records;
        });
    }   
});

我使用了RESTAdapterfindAll的实现,只是更改了 url,以匹配你想要的。

但是,如果您的响应只返回一个对象,我认为该find方法更好:

...
find: function(record, id) {
    var url = '/api/users/' + $.cookie('user_id'),
        self = this;

    return this.ajax(url).then(function(data) {
      self.didFind(record, id, data);
      return record;
    });
},
...
于 2013-08-21T20:23:33.937 回答
1

多亏了 Erik Bryn 的这个 jsFiddle,我终于找到了解决问题的方法。

我在这里错过了一个return

App.Profile.adapter = Ember.Adapter.create {

  findAll: (klass, records) ->
    $.ajax('/api/users/' + $.cookie('user_id'), {
      type: 'get'
      headers: {
        'Content-Type': 'application/json'
        'Authentication-Token': $.cookie('token')
      }
      dataType: 'json'
    }).then (res) ->
      profiles = []
      // some stuff done here
      records.load klass, profiles
      return records // HERE

}

另外,我现在使用我的init方法ProfilesIndexRoute而不是redirect

App.ProfilesIndexRoute = Ember.Route.extend {

  init: ->
    App.Profile.fetch().then (profiles) =>
      @transitionTo 'profile', profiles.get('firstObject')

}
于 2013-08-21T22:17:59.373 回答