嵌套的诺言直到单击按钮后才解决 [英] Nested promises not resolving until a button is clicked

查看:90
本文介绍了嵌套的诺言直到单击按钮后才解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆