嵌套的诺言直到单击按钮后才解决 [英] Nested promises not resolving until a button is clicked
问题描述
我正在构建一个AngularJS应用程序(使用1.2.0 RC1),该应用程序使用REST API来保存用户输入的数据.用户将输入有关公司的数据,该数据包含我需要保存的两个核心组件:
I'm building an AngularJS app (using 1.2.0 RC1) that uses a REST API for saving data that the user has entered. The user will enter data about a company and it consists of two core components that I need to save:
- 公司详细信息
- 该公司内的联系人
我要调用1种REST方法来保存公司,然后我要调用另一种方法来保存每个联系人.
I have 1 REST method to call to save the company and then I have another that I call for each contact to be saved.
我计划使用$q
跟踪所有请求,并在完成后对其进行解决.
I planned to use $q
to track all the requests and resolve them once it's completed.
我遇到的问题是,尽管REST API被成功调用并且我的所有数据都已保存,但是当所有的诺言都解决了时,我的控制器没有收到通知.直到屏幕上的按钮,例如add contact
按钮.我曾尝试消除REST API作为问题的根源,但是在使用setTimeout
模拟延迟的作业时,仍然会发生这种情况.
The problem I've hit is that although the REST API is being called successfully and all my data is being saved my controller isn't being notified when all the promises have resolved until I click a button on the screen, such as the add contact
button. I've tried eliminating the REST API as a source of problems but it still happens when simulating delayed jobs using setTimeout
.
这是我的service
模块:
angular.module('myApp', ['restService'])
.factory('service', ['client', '$q', function (client, $q) {
return {
create: function (name, people) {
var deferred = $q.defer();
setTimeout(function () {
console.log('saved company ' + name);
var promises = people.map(function (person) {
var dfd = $q.defer();
setTimeout(function () {
console.dir(person);
console.log('Person saved');
dfd.resolve();
}, 100);
return dfd.promise;
});
$q.all(promises).then(deferred.resolve);
}, 100);
return deferred.promise;
}
};
}]);
这是我的控制器:
angular.module('club', ['myApp'])
.controller('RegisterCtrl', ['$scope', 'service', function ($scope, service) {
$scope.addPerson = function () {
$scope.company.people.push({
firstName: '',
lastName: '',
email: ''
});
};
$scope.removePerson = function (person, index) {
$scope.company.people.splice(index, 1);
};
$scope.save = function (company) {
service.createClub(company.name, company.people).then(function () {
console.log('And we\'re done');
});
};
$scope.company = {
name: '',
people: []
};
}]);
因此,当我调用save
方法(绑定到按钮的ng-click
)时,将具有如下所示的console.log设置:
So when I invoke the save
method (which is ng-click
bound to a button) I will have a console.log set like this:
saved company
Object
Person saved
Object
Person saved
请注意,没有And we're done
输出.一旦单击绑定到addPerson
的按钮,我就会得到最终的消息输出.
Notice there's no And we're done
output. As soon as I click the button that addPerson
is ng-click
bound to I get the final message output.
推荐答案
Angular不会神奇地监视所有超时.它需要一个钩子来告知某些内容可能已更改,从而触发$digest
循环.
Angular doesn't magically watch all timeouts. It needs a hook to be told that something might have changed, which triggers a $digest
loop.
您可以通过调用$scope.$apply()
或使用内置的处理程序(例如ng-click
)手动进行操作.但是对于此用例,还可以使用$timeout
服务来代替setTimeout
.
You can do it manually, by calling $scope.$apply()
, or by using inbuilt handlers (like ng-click
). But for this use case there's also the $timeout
service which you can use in place of setTimeout
.
请参见 API参考/ng/$ timeout .
这篇关于嵌套的诺言直到单击按钮后才解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!