16

ember-data は本番環境に対応しておらず、まだ変化しているため、使用しないことにしました。とにかく、私のアプリはいくつかの ajax リクエストを行うだけでよいので、それほど大きな違いはありません。ajax promise 応答の処理方法がわかりません。

ユーザーがアプリをロードすると、認証済みのセッションが既に存在します。そのユーザー情報についてサーバーにpingを実行し、テンプレートに表示しようとしています。私のテンプレートは、私の ajax リクエストが結果を返す前にレンダリングされ、約束に従って更新されないようです。

// route
App.ApplicationRoute = Ember.Route.extend({
    setupController: function(){
        this.set("currentUser", App.User.getCurrentUser());
    }
});


// model
App.User = Ember.Object.extend({
    email_address: '',
    name_first: '',
    name_last: '',
    name_full: function() {
        return this.get('name_first') + ' ' + this.get('name_last');
    }.property('name_first', 'name_last')
});
App.User.reopenClass({
    getCurrentUser: function() {
        return $.ajax({
            url: "/api/get_current_user",
            type: "POST",
            data: JSON.stringify({})
        }).then(function(response) {
            return response;
        });
    }
});

私のテンプレートでは:

<h1> Hey, {{App.currentUser.name_first}}</h1>

応答を受け取ったとき、または応答があるまでレンダリングを遅らせたときにテンプレートを更新するにはどうすればよいですか?

4

3 に答える 3

37

実際、答えは非常に簡単です。Promise を使用する必要はありません。代わりに、空のオブジェクトを返します。コードは次のようになります。

App.User.reopenClass({
    getCurrentUser: function() {
        var user = App.User.create({}); //create an empty object
        $.ajax({
            url: "/api/get_current_user",
            type: "POST",
            data: JSON.stringify({})
        }).then(function(response) {
            user.setProperties(response); //fill the object with your JSON response
        });
        return user;
    }
});

ここで何が起きてるの?

  1. 空のオブジェクトを作成します。
  2. API への非同期呼び出しを行います...
  3. ...そして、成功のコールバックで、空のオブジェクトを埋めます。
  4. ユーザー オブジェクトを返します。

注:実際に何が起こっているのですか?上記の流れは、これらのアクションが発生する順序ではありません。実際には、ポイント 1、2、および 4 が最初に実行されます。その後しばらくして、サーバーから応答が返されると、3 が実行されます。したがって、アクションの実際の流れは、1 -> 2 -> 4 -> 3 です。

したがって、一般的なルールは、Ember がそのロジックを実行できるようにするオブジェクトを常に返すことです。あなたのケースでは最初に値は表示されず、オブジェクトが満たされると、Ember はその魔法を開始し、テンプレートを自動更新します。あなたの側で難しい仕事をする必要はありません!


最初の質問を超えて、配列でこれを行うにはどうすればよいでしょうか? この一般的な規則に従って、空の配列を返します。バックエンドからすべてのユーザーを取得したい場合を想定した小さな例を次に示します。

App.User.reopenClass({
    getAllUsers: function() {
        var users = []; //create an empty array
        $.ajax({
            url: "/api/get_users",
        }).then(function(response) {
            response.forEach(function(user){
                var model = App.User.create(user); 
                users.addObject(model); //fill your array step by step
            });
        });
        return users;
    }
});
于 2013-03-25T09:22:35.243 に答える
6

前に述べたように、空の配列を返す代わりに Ember.Deferred を使用します。

App.User.reopenClass({
  getAllUsers: function() {
    var dfd = Ember.Deferred.create();
    var users = [];

    $.ajax({
        url: "/api/get_users",
    }).then(function(response) {
        response.forEach(function(user){
            var model = App.User.create(user); 
            users.addObject(model);
        });
        dfd.resolve(users);
    });
    return dfd;
  }
});

モデルフックで行う必要があるのはこれだけです

model: function(){
  return App.User.getAllUsers();
}

Ember は十分に賢く、返された promise を処理する方法を知っています。モデルが正しく設定されると解決されると、jQuery promise を返すこともできますが、奇妙な動作が発生します。

于 2013-06-13T15:52:55.880 に答える