没有Ember Data的AJAX承诺

use*_*427 16 asynchronous ember.js

我决定不使用余烬数据,因为它不是生产就绪并且仍在改变.我的应用程序只需要做一些ajax请求,所以它不应该产生太大的差异.我无法理解如何处理ajax promise响应.

当我的用户加载应用时,他们已经有一个经过身份验证的会话.我正在尝试ping服务器以获取该用户信息并将其显示在我的模板中.看来我的模板在我的ajax请求返回结果之前呈现,然后不会使用promise更新.

// 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;
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

在我的模板中:

<h1> Hey, {{App.currentUser.name_first}}</h1>
Run Code Online (Sandbox Code Playgroud)

在收到响应或延迟呈现之前,如何在响应之前更新模板?

mav*_*ein 37

实际上答案很简单:你不需要使用诺言.而只是返回一个空对象.您的代码可能如下所示:

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;
    }
});
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

  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;
    }
});
Run Code Online (Sandbox Code Playgroud)


Dan*_*rra 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;
  }
});
Run Code Online (Sandbox Code Playgroud)

在您的模型钩子中,您所要做的就是这个

model: function(){
  return App.User.getAllUsers();
}
Run Code Online (Sandbox Code Playgroud)

Ember是聪明的,并知道如何处理你返回的承诺,一旦解决了模型将被正确设置,你也可以返回一个jQuery承诺,但它会给你一些奇怪的行为.

  • 只是注意到Ember.Deferred似乎[现在已经弃用了RSVP.promise](http://emberjs.com/guides/deprecations/#toc_deprecate-ember-deferredmixin-and-ember-deferred). (3认同)