AngularJS - 如何及时刷新控制器属性

时间:2014-12-07 12:58:27

标签: javascript angularjs

以这个非常简单的应用程序为例。

视图

<div ng-controller="filesController as filesCtrl">
    <div ng-repeat="file in filesCtrl.files">
        <p>{{file.percent}}% completed of file ID : {{file.id}}</p>
    </div>
</div>

控制器

app.controller('filesController', function(){
   this.files = files; // the files variable loaded globally as cdata;
});

因此,这段代码显示了服务器中文件的当前进度。现在,我需要为每个文件连接到服务器以及时获得百分比(一次在30秒内)。

我研究过尝试创建服务。

服务

app.factory('fileProcessingStatus', ['$http', '$interval', function($http, $interval){
    var service = {};
    service.status = {};
    service.file_id = 0;
    service.isComplete = false;
    service.interval = {};

    service.getCurrentStatus = function(file_id){
        var url = app.ajaxUrl + '?action=file_processing_status&file_id=' + file_id;

        $http.get(url)

        .success(function(data){

                console.log(data);

            if(data == 0){
                service.status = 0;
            }else{
                service.status = data;
                // check data and set isComplete as true when file is finished processing
                if(service.data.status == 'processed'){
                    service.stopChecking();
                }
            }
        })
        .error(function(){
            service.status = 0;
        });

    };

    service.startChecking = function(file_id){
        service.file_id = file_id;
        service.interval = $interval(getCurrentStatus(file_id), 30 * 1000);
    };

    service.stopChecking = function(){
        $interval(service.interval);
    };

}]);

该服务打算每隔30秒向服务器发送查询,但我不知道如何将文件ID传递给服务。如果我说5个文件服务应该为所有5个文件独立调用。

2 个答案:

答案 0 :(得分:0)

$ http不会公开xhr,因此您无法注册onprogress事件。

看看how to add Angular $http event listeners

答案 1 :(得分:0)

为了创建每个文件的检查,我们需要为每个文件创建单独的$scope。因此修改后的代码将如下所示。

更改视图

需要新的控制器为每个file变量创建不同的范围,并通过file传递ng-init。目前我不知道使用ng-init是否是最佳做法。如果您认为有更好的解决方案,请随意启发。

<div ng-controller="filesController as filesCtrl">
    <div ng-repeat="file in filesCtrl.files">
        <!-- Notice the new controller -->
        <p ng-controller="ProgressUpdate as progressUpdate" ng-init="init(file)">{{file.percent}}% completed of file ID : {{file.id}}</p>
    </div>
</div>

介绍新控制器(删除服务)

// we still need the older one

app.controller('filesController', function(){
   this.files = files; // the files variable loaded globally as cdata;
});

// new controller

 app.controller('ProgressUpdate', ['$http', '$interval', '$scope', function($http, $interval, $scope){
        $scope.status = {};
        $scope.file_id = 0;
        $scope.isComplete = false;
        $scope.interval = {};

        $scope.init = function(file){
            $scope.startChecking(file.id);
            $scope.file = file;
        };

        $scope.startChecking = function(file_id){
            $scope.interval = $interval(function(){
                    $scope.getCurrentStatus(file_id)
                }
                , 30 * 1000);
        };

        $scope.stopChecking = function(){
            $scope.isComplete = true;
            $interval.cancel($scope.interval);
        };

        $scope.getCurrentStatus = function(file_id){
            var url = app.ajaxUrl + '?action=get_file_info&id=' + file_id;

            $http.get(url)

                .success(function(data){
                    var file = $scope.file;

                    if(data == 0){
                        // handle error
                    }else{

                        if(file.status != 'lock'){
                            var processed = data.listing_processed;
                            var percent = (processed/file.total ) * 100;
                            file.percent = percent.toFixed(2);
                        }

                        // check data and set isComplete as true when file is finished processing
                        if(data.status == 'processed'){
                            $scope.stopChecking();
                        }
                    }

                })
                .error(function(){
                    // handle error
                });

        };

    }]);

一旦我们在file控制器中获得ProgressUpdate,我们现在可以创建http请求并从服务器获取数据。成功获取数据后,我们更新file变量。 Angulars的双向数据绑定会照顾剩下的视图自动更新。