等待在Angular JS中完成的功能

时间:2015-04-13 17:01:39

标签: javascript angularjs

我遇到以下情况:当我的应用程序首次运行时,在.run函数中,我发出一个http请求来获取“监视器”列表。收到后,它会填充服务中的监视器阵列。许多控制器使用此服务来共享数据。此服务称为ZMDataModel。 ZMDataModel提供了一个名为isMonitorsLoaded()的函数。当这返回1时,我知道监视器数组已填充(并且http调用已完成)

现在,我有一个名为Monitors的页面,其控制器是zmApp.MonitorCtrl,如下所示。我需要做的是,在这个MonitorCtrl中,基本上,就在开始时,做一个相当于:

while (ZMData.isMonitorsLoaded()!=1);

现在我显然不能这样做,因为它锁定了我的浏览器,并且浏览器从来没有机会将isMonitorLoaded设置为1,所以它变成了无限循环。

我知道我需要以某种方式暂停,但不能完全遵循我在控制器中需要做的事情。我的控制器代码如下:

angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', function($scope, $http, ZMHttpFactory, ZMDataModel) {

  $scope.monitors = [];
  
            
  console.log("***Waiting for Monitors to load before I proceed");
  // I can't do a tight loop waiting for ZMDataModel.isMonitorsLoaded
  // so some timeout?
  
    $scope.monitors = ZMDataModel.getMonitors();
    
    console.log("I GOT " + $scope.monitors);


$scope.doRefresh = function() {
    console.log("***Pull to Refresh");                                           
    $scope.monitors = [];
    ZMHttpFactory.getMonitors().then(function(data) {
    $scope.monitors = data;
    $scope.$broadcast('scroll.refreshComplete');
    console.log("I GOT " + $scope.monitors);
  });
};
                                               
});

2 个答案:

答案 0 :(得分:1)

您可以$rootScope.$emit('eventName')使用$rootScope.$on('eventName'),其功能就像是为任何订阅它们的人播放事件// In your monitor loaded method: onload: function(){ //Here you can pass optional information to the listeners // for Example an array of monitor or an object $rootScope.$emit('MONITORS_LOADED',{ monitors: getMonitors() }); } // In your controller: angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', function($rootScope, $scope, $http, ZMHttpFactory, ZMDataModel) { $scope.monitors = []; $rootScope.$on('MONITOR_LOADED', function(event, data) { $scope.monitors = data; // or // $scope.monitors = ZMDataModel.getMonitors(); console.log("I GOT " + $scope.monitors); } $scope.doRefresh = function() { //... }); }; });

{{1}}

答案 1 :(得分:1)

为什么不使用在加载监控服务器时解决的承诺?您可以将服务设置为:

angular.module('myApp')
    .service ('ZMDataModel', ['$http', function ($http) {

    function MyServices () {
        var _deferred;
        var _isLoading;
        var me = this;

        this.isLoaded = false;

        this.load = function (reload) {

            if (!_deferred || (!_isLoading && reload)) {
                this.isLoaded = false;
                _deferred = $q.defer();

                _isLoading = true;

                // make your call
                $http ({get : 'http://your-site.com'})
                    .then (
                        function success (rawData) {
                            me.isLoaded = true;
                            // parse your data
                            me.monitors = rawData;

                            _deferred.resolve(me);
                        },
                        function fail (error) {
                            _deferred.reject(error);
                            _deferred = null;

                            if (onFail) {
                                me.monitors = [];
                            }
                        }
                    )
                    .finally (
                        function () {
                            _isLoading = false;
                        }
                    );
            }

            return _deferred.promise;
        };
    }

    return MyServices;

    }
]);

现在,您可以在任何地方使用您的服务:

angular.module(' zmApp.controllers')。控制器(' zmApp.MonitorCtrl',[' $ scope',' ZMDataModel' ;,function($ scope,ZMDataModel){

    $scope.monitors = [];


    console.log("***Waiting for Monitors to load before I proceed");
    // I can't do a tight loop waiting for ZMDataModel.isMonitorsLoaded
    // so some timeout?

    ZMDataModel.load ().then (
        function (response) {
            $scope.monitors = ZMDataModel.monitors;
        }
    );

    $scope.doRefresh = function() {
        console.log("***Pull to Refresh");
        $scope.monitors = [];
        ZMDataModel.load (true).then (
            function (response) {
                $scope.monitors = ZMDataModel.monitors;
            }
        );
    };

}]);    

如果其他控制器首先加载服务并不重要。只要您使用加载功能而不使用'刷新'标志设置为true,服务不会再次加载