Angular,如何知道服务何时完成

时间:2014-01-30 23:44:36

标签: javascript ajax angularjs

我试图在函数有效时使用ajax微调器,但我不知道如何告诉微调器在函数完成时隐藏。

代码的工作原理如下:

  1. 单击按钮,将显示微调器,并触发控制器中的某个功能以更新某些数据。
  2. 该函数访问使用$ resource更新数据的服务
  3. 无法隐藏微调器,因为我不知道该过程何时完成。
  4. 那么,我怎么知道整个事情何时完成所以我可以放弃显示微调器?

    单击视图中的按钮会触发updateData()。在我的控制器中,我有:

    $scope.updateData = function () {
        Data.updateData();
    }
    

    上面引用的数据服务的updateData方法是:

    updateData : function() {
    
               API.update({
                   uri     : 'updateData'
               }, {
                   data     : data
               }, function(data) {
                   data = data[0];
                   $rootScope.$emit('Data.updateSuccess');
    
               }, function(err) {
                   $rootScope.$emit('Data.updateError', err);
               });
    

    该API来自扩展$ resource的工厂:

    .factory('API', ['$resource', function($resource){
        return $resource('/location/:uri', {}, {
            query : {
                method  : 'GET',
                isArray : true
            },
            update: {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                }
            },
            create: {
                method: 'POST',
                isArray : true,
                headers: {
                    'Content-Type': 'application/json'
                }
            }
        });
    }]);
    
    }
    

    起初我以为我可以在控制器中监听那些$ emits(我也试过$ broadcast)

        $rootScope.$on('Data.updateSuccess', $log.log('update success'));
        $rootScope.$on('Data.updateError', $log.log('update failure'));
    

    但是当我这样做时,我每次都会得到它们。那么在完成此更新过程时,我需要做些什么来确定何时隐藏我的ajax微调器?

2 个答案:

答案 0 :(得分:2)

您可以使用promises来处理此问题。对于承诺,请注入$ q服务。

通过调用$ q.defer()获得推迟;

然后,你以异步方式做某事。在您的示例中,您将进行资源调用。从资源调用中获取数据时,可以使用数据调用deferral.resolve。那时你也可以通过$ scope或通过调用服务来关闭微调器。

这是一个模拟获取数据2秒延迟的示例服务。它向您展示了如何使用$ q服务。而不是$ timeout只是想象你打电话给$ resource。

app.service("myService", function($q, $timeout) {
    var _this = this;
    this.$q = $q;
    this.$timeout = $timeout;
    var stuff = [1, 2, 3]; 
    return {
        getStuff: function() {
            var deferral = $q.defer(); 
            _this.$timeout(function() {
                deferral.resolve(stuff); 
            }, 2000);
            return deferral.promise;
        }
    };
});

接下来,这是一个使用promise的控制器。请注意,它会打开微调器,然后提取数据,并在数据到达时将其关闭。同样,我通过范围执行此操作,但您可以调用服务或发出事件,具体取决于您的微调器的实现方式。

app.controller("myController", function($scope, myService) {
    var _this = this;
    this.$scope = $scope;
    this.myService = myService;
    this.$scope.showSpinner = true; 
    this.myService.getStuff().then(function(data) {
        _this.$scope.stuff = data;
        _this.$scope.showSpinner = false;
    });
});

以下是完整的工作小提琴:http://jsfiddle.net/jeremylikness/PhZYb/

答案 1 :(得分:1)

这样的事情应该对你有用。 $ resource实例返回您可以访问的承诺(无需手动注入$ q服务):

    updateData: function() {

        var Data = API.update({ ... your opts ... });

        // access the built-in $promise 
        Data.$promise.then(function(res){

            // $broadcast from $rootScope
            $rootScope.$broadcast('Data.updateSuccess');

        }, function(err){

             $rootScope.$broadcast('Data.updateError', err);

        });
    }

有了这些见解: