2013-08-21 4 views
0

J'essaie de faire quelques trucs de base avec Ember Model mais je rencontre des comportements étranges avec des promesses. Je ne suis pas sûr de comprendre très bien comment ça fonctionne.Problème avec les promesses du modèle Ember

Alors, j'ai cet itinéraire:

App.ProfilesIndexRoute = Ember.Route.extend { 

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

} 

Je veux simplement les gens à être redirigés vers /profiles/123 (= le premier profil) lorsqu'ils accèdent /profiles.

Voici l'adaptateur Profil:

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 

} 

Quand je vais à /profiles, voici ce que je vois dans ma console:

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

0 est le résultat de console.log profiles.get('length'). Il semble que ça s'appelle avant que l'appel AJAX ait eu la chance de finir. Ce que je devrais avoir dans ma console est quelque chose comme ceci:

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

Qu'est-ce que je fais mal ici? Quelqu'un here m'a suggéré d'utiliser fetch au lieu de find mais cela ne semble pas résoudre mon problème car les choses ne sont pas exécutées dans le bon ordre.

Merci!

Répondre

1

j'ai finalement trouvé comment résoudre le problème grâce à this jsFiddle by Erik Bryn.

je manque un return ici:

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 

} 

Aussi, je vais maintenant utiliser la méthode init dans mon ProfilesIndexRoute au lieu de redirect:

App.ProfilesIndexRoute = Ember.Route.extend { 

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

} 
1

Vous devriez rediriger vers un itinéraire différent du crochet afterModel:

App.ProfilesIndexRoute = Ember.Route.extend { 

    model: -> 
    App.Profile.fetch() 

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

} 

De plus, puisque vous utilisez @, vous devez utiliser la graisse flèche => pour avoir la bonne référence à this.

Espérons que ça aide.

1

Je pense que la façon dont vous overring l'adaptateur est erroné:

Vous utilisez le ajax jquery différé. Mais je pense que vous devez wrap that call in RSVP. Parce que les braises utilisent le RSVP pour gérer les promesses.

Donnez un coup d'oeil dans cette mise en œuvre

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; 
     }); 
    } 
}); 

je la mise en œuvre de findAllRESTAdapter et juste changé l'URL, pour correspondre à ce que vous voulez.

Mais si votre réponse retourne un seul objet, je pense que la méthode find est mieux:

... 
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; 
    }); 
}, 
... 
Questions connexes