我决定不使用ember-data,因为它不是生产就绪并且仍在改变。我的应用程序只需要做一些ajax请求,所以它不应该产生太大的差异。我无法理解如何处理ajax承诺响应。
当我的用户加载应用时,他们已经拥有经过身份验证的会话。我正在尝试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;
});
}
});
在我的模板中:
<h1> Hey, {{App.currentUser.name_first}}</h1>
在收到回复或延迟呈现之前,如何更新模板,直到我收到回复?
答案 0 :(得分: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;
}
});
这里发生了什么?
注意:实际发生了什么?上面提到的流程不是这些操作发生的顺序。实际上,首先执行点1,2和4。然后一段时间后,当响应从服务器返回时,执行3。 所以真正的行动是:1 - &gt; 2 - &gt; 4 - &gt; 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;
}
});
答案 1 :(得分: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是聪明的,并知道如何处理你返回的承诺,一旦解决了模型将被正确设置,你也可以返回一个jQuery承诺,但它会给你一些奇怪的行为。
答案 2 :(得分:0)
您也可以将当前用户设置为ApplicationRoute的模型,如下所示:
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return App.User.getCurrentUser();
}
});
由于getCurrentUser()
返回一个承诺,转换将暂停,直到承诺完成或拒绝。
这很方便,因为在转换完成时,您的模型已初始化,您将看到它在模板中呈现。
你可以在Ember指南中read up more about async routing。