AngularJS无法重复服务内部的异步功能

时间:2015-09-14 19:04:28

标签: angularjs loops asynchronous service

我正在构建一个表单,可以使用AngularJS将缓存的JSON数据发送和清除到RESTful Web服务。当我单击提交时,当前表单数据缓存在JSON对象中,然后我通过Web服务发送该数据。一旦发送,我清除缓存。

我有一个我希望在多个控制器中使用的功能(发送缓存数据)。它遍历缓存,一次发送一个JSON对象。当我在单个控制器中具有该功能时,代码工作正常。但是一旦我将它包装在服务中并通过控制器调用它,我的循环就不再有效了。如果只有一个缓存对象,它运行正常。但如果有超过1个,那么" this.sendCache()"不会开枪。我相信这与异步功能有关,我不知道该怎么做。非常感谢帮助!!!

控制器

app.controller('FormCtrl', function($scope, $filter, $window, getData, Post, randomString, $cordovaProgress, $cordovaDialogs, scService) {

    $scope.submitEntry = function() {

        var frmData = new Post($scope.postData);
        var postCount = window.localStorage.getItem("localPostCount");
        postCount ++;

        window.localStorage.setItem("localPostCount", postCount);
        window.localStorage.setItem("post" + postCount, JSON.stringify(frmData));

        scService.sendCache();

    };

});

服务

app.service('scService', function ($window, Post, $cordovaProgress, $cordovaDialogs, $timeout) {

    this.sendCache = function () {
        if(window.Connection){
            if(navigator.connection.type != Connection.NONE) {

                var postCount = window.localStorage.getItem("localPostCount");
                var curCacheObj = new Post(JSON.parse(window.localStorage.getItem("post" + postCount) || '{}'));

                if (postCount > 0) {
                    curCacheObj.$save().then(function(response) {
                        var servResponse = JSON.stringify(response);
                            if (servResponse.indexOf("@xmlns:ns3") > -1) {
                                console.log("Post " + postCount + " sent!");
                            }
                            else {
                                console.log("Unable to post at this time!");
                            }
                        }).then(function() {
                            window.localStorage.removeItem("post" + postCount);
                            postCount --;
                            window.localStorage.setItem("localPostCount", postCount);
                        }).then(function() {
                            console.log(postCount); //log shows 1
                            if (postCount > 0) {
                                    this.sendCache(); //yet this won't fire again!
                                }
                                else {
                                    $cordovaDialogs.alert('Submission recorded successfully', 'Success', 'OK').then(function() {
                                      console.log('Submission Success');
                                      $window.location.href= 'index.html';
                                    });
                                }
                    });
                }
                else {
                $cordovaDialogs.alert('Submission recorded successfully', 'Success', 'OK').then(function() {
                  console.log('Submission Success');
                  $window.location.href= 'index.html';
                });
                }
            }
            else {
                $cordovaDialogs.alert('Your current connection is too slow. Sync at a later time by returning to the app with a better connection.', 'Submission Stored', 'OK').then(function() {
                  console.log('Submission Cached');
                  $window.location.href= 'index.html';
                });
            }
        }
    };

});

1 个答案:

答案 0 :(得分:1)

这实际上是一个非常常见的JS问题,与AngularJS本身无关。 this不是您认为的那样。在.then()回调中,您的上下文已更改,因此它不再指向您的服务,而是指向异步调用的响应上下文。因此,函数sendCache()实际上并不存在,也不能以这种方式调用。

您需要做的就是在服务顶部引用self

var self = this;

然后在通话中使用self代替this

self.sendCache();

请注意,对于像postCount这样的变量,这不会给您带来麻烦,因为它们在闭包中本地定义,并且不需要引用this。但是,如果您要在服务中定义this.postCount或其他变量,则需要执行相同的操作。