3

我正在使用 AngularJS 和ngProgress在我的网站顶部显示一个类似 YouTube 的加载栏。

启动栏,然后通过ajax加载新数据,一旦请求完成,栏就完成了。

例子:

var TestCtrl = function( $scope, $location, Tests, ngProgress ) 
{
    // start progressbar
    ngProgress.start();

    $scope.tests = Tests.query(
        function()
        {
            // end progressbar
            ngProgress.complete()
        }
    );
};  

现在我的问题是:我怎样才能将这个原则按照事物的顺序向上集成,这样我就不必为每个控制器重复代码?

4

4 回答 4

2

您可以使用控制 ngProgress 的服务(充当它的包装器)并侦听 url 中的更改。

  • 每次 url 更改时,$locationChangeSuccess都会广播事件(更多信息在$location),我们可以监听调用ngProgress.start()
  • 但是我们不知道它什么时候完成(我们不能永远在顶部加载一个栏),因此我们需要ngProgress.complete()在我们的控制器中显式调用,或者我们可以假设我们的异步函数可能需要大约 5 秒才能完成并且ngProgress.complete()在我们的包装服务中使用计时器调用
  • 当加载栏已经可见并且 url 发生变化时,我们需要通过调用重置栏的状态ngProgress.reset()

您可以使用以下方法来解决这些问题:

angular.module('myApp').factory('Progress', function (ngProgress) {
    var timer;
    return {
        start: function () {
            var me = this;
            // reset the status of the progress bar
            me.reset();
            // if the `complete` method is not called
            // complete the progress of the bar after 5 seconds
            timer = setTimeout(function () {
                me.complete();
            }, 5000);
        },
        complete: function () {
            ngProgress.complete();
            if (timer) {
                // remove the 5 second timer
                clearTimeout(timer);
                timer = null;
            }
        },
        reset: function () {             
            if (timer) {
                // remove the 5 second timer
                clearTimeout(timer);
                // reset the progress bar
                ngProgress.reset();
            }
            // start the progress bar
            ngProgress.start();
        }
    };
});

要监听 url 的变化并显示我们可以使用的进度条:

angular.module('myApp')
    .run(function (Progress) {
        $rootScope.$on('$locationChangeSuccess', function () {
            Progress.start();
        });
    }

现在我们可以通过注入Progress服务并在所有异步函数完成时调用该方法来手动控制状态栏的完整性Progress.complete()(我们也可以通过任何进行异步调用的服务来控制它):

angular.module('myApp')
    .controller('SomeCtrl', function (Progress) {
        setTimeout(function () {
            Progress.complete();
        }, 2000);
    });
于 2014-02-22T21:24:53.273 回答
1

这是使用拦截器的示例:

.factory('interceptorNgProgress', [
    'ngProgressFactory', function (ngProgressFactory) {

var complete_progress, getNgProgress, ng_progress, working;
ng_progress = null;
working = false;

getNgProgress = function() {

    if(!ng_progress) {

        ng_progress = ngProgressFactory.createInstance();

        return ng_progress;
    }

    return ng_progress;
};

complete_progress = function() {
    var ngProgress;
    if (working) {
        ngProgress = getNgProgress();
        ngProgress.complete();
        return working = false;
    }
};

return {
    request: function(request) {
        var ngProgress;
        ngProgress = getNgProgress();
        if (request.url.indexOf('.html') > 0) {
            return request;
        }
        if (!working) {
            ngProgress.reset();
            ngProgress.start();
            working = true;
        }
        return request;
    },
    requestError: function(request) {
        complete_progress();
        return request;
    },
    response: function(response) {
        complete_progress();
        return response;
    },
    responseError: function(response) {
        complete_progress();
        return response;
    }
}
}])

.config(function ($httpProvider) {
    $httpProvider.interceptors.push('interceptorNgProgress');
});
于 2015-10-12T12:05:30.747 回答
0

您显然已经有了Tests服务。覆盖它,因此ngProgress被注入其中并始终Tests为您调用.ngProgress.start()ngProgress.complete()query

于 2013-12-04T21:25:19.273 回答
0

我会把它放在一个角度指令中,然后你可以将它传递给你希望能够使用它的任何控制器。

http://docs.angularjs.org/guide/directive

编辑,考虑一下这种情况下的服务可能会更好。

http://docs.angularjs.org/guide/dev_guide.services.creating_services

于 2013-09-18T16:25:38.997 回答