【问题标题】:Best way to initialize a controller with several ajax requests使用多个 ajax 请求初始化控制器的最佳方法
【发布时间】:2016-02-29 22:11:53
【问题描述】:

我有 2 个 $http 函数,我使用 ng-init 调用它们,因为它们返回的数据会填充页面。

ng-init = "getOpen(); getClosed();"

这是最好的方法吗?

第一个函数;

$scope.getOpen = function () {
    $http({
        method: 'post',
        url: "http://www.example.co.uk/php/open-get.php",
        data: $.param({ 'location' : $scope.l, 
                       'time' : $scope.t,
                       'day' : $scope.d,
                       'type' : 'get_restopen' }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).
    success (function(data, status, headers, config){
        if(data.success && !angular.isUndefined(data.data) ){
            $scope.open = data.data;
        } else {
            $scope.open = [];
        }
    }).
    error(function(data, status, headers, config) {
        //$scope.messageFailure(data.message);
    });
}

第二个功能;

$scope.getClosed = function () {
    $http({
        method: 'post',
        url: "http://www.example.co.uk/php/closed-get.php",
        data: $.param({ 'location' : $scope.l, 
                       'time' : $scope.t,
                       'day' : $scope.d,
                       'type' : 'get_restopen' }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).
    success (function(data, status, headers, config){
        if(data.success && !angular.isUndefined(data.data) ){
            $scope.closed = data.data;
        } else {
            $scope.closed = [];
        }
    }).
    error(function(data, status, headers, config) {
        //$scope.messageFailure(data.message);
    });
}

一切都很好。我的问题是我猜这是在 AngularJS 中做事的一种有效方式吗?我是 Angular 新手,所以只是寻求指导。

1 - 我的$http 是否同时执行?还是一个在另一个开始之前完成?

2 - 是否需要在我的代码中引入$qpromises?功能相互独立

3 - 无论成功与否,我如何检测所有 $http 请求何时完成

下面的代码正确吗?

$q.all([$scope.getOpen, $scope.getClosed]).then(function() {
     //Both requests have been completed and I shall now set a bolean
     $scope.compelete = true;
});

【问题讨论】:

  • 我只想要快速/高效的执行,就是这样

标签: javascript angularjs


【解决方案1】:
  1. 假设您自己在某处调用这两种方法,是的。 $http 调用默认是异步的

  2. 已经完成,$http 实际上返回了一个承诺!

  3. promise.all() 是一种无需修改 promise 返回的优雅方式。它实际上是一个完成观察者。更多详情请关注promise reference

【讨论】:

  • $q.all([getOpen(), getClosed()]).done(function (values) { assert(values[0] === values[1]); $scope.complete = true; });
【解决方案2】:

我有 2 个使用 ng-init 调用的 $http 函数,因为数据 他们返回填充页面。

ng-init = "getOpen(); getClosed();"

这是最好的方法吗?

如角度文档所述:

这个指令可以被滥用来添加不必要的逻辑量 你的模板。 ngInit 只有少数合适的用法,例如 至于 ngRepeat 的别名特殊属性,如演示中所见 以下;以及通过服务器端脚本注入数据。除了这些 在少数情况下,您应该使用控制器而不是 ngInit 来初始化 范围内的值。

你可以在这里找到它:https://docs.angularjs.org/api/ng/directive/ngInit

你应该避免在你的模板中使用 ng-init。在控制器中启动某些东西的推荐用法是直接在控制器内部调用私有函数。

我还建议阅读有关 angular 的样式指南:
https://github.com/johnpapa/angular-styleguide

1 - 我的 $http 是否同时执行?或者是之前完成的 另一个开始了?

这两个呼叫几乎同时启动。然后,当他从您的服务器获得答案时,javascript 会保存一堆他必须执行的回调。只需在浏览器中按 F12 并找到“网络”选项卡即可查看正在启动的所有请求。

此外,“.success”现在已被弃用。你应该使用'.then' https://docs.angularjs.org/api/ng/service/$http#deprecation-notice

2 - 是否需要在我的代码中引入 $q 或承诺?这 功能相互独立

在这种情况下不是。如果你想在两个调用都执行后执行某些东西,你可以使用$q.all([promise1, promise2])

3 - 我如何检测所有 $http 请求何时完成,无论 是否成功

看看 $httpInterceptors。给大家分享一段我实现的代码

angular.module("myModule").factory("myHttpInterceptor", [
    "LoadingService",
    "$q",
    "Alert",
    function (LoadingService, $q, Alert) {

        function requestInterceptor(config) {
            LoadingService.increaseCounter();
            return config;
        }

        function responseInterceptor(response) {
            LoadingService.decreaseCounter();
            return response;
        }
   // ...

下面的代码正确吗?

$q.all([$scope.getOpen, $scope.getClosed]).then(function() {
     //Both requests have been completed and I shall now set a bolean
     $scope.compelete = true;
});

不,因为您仍然承诺将由您的函数返回。此外,“.success”没有实现承诺链。你现在必须使用'.then()'

$scope.getOpen = function () {
    return $http({
        // config
    }).
    then(function(data, status, headers, config){
        //handling success
    },(function(data, status, headers, config) {
        //handling error
    });

总结:

angular.module("yourApp").controller("someController", ["$scope", "$q"
    function($scope, $q){

        // init
        init();

        // Shared functions

        $scope.getOpen = function () {
          return $http({
             method: 'post',
             url: "http://www.example.co.uk/php/open-get.php",
             data: $.param({ 'location' : $scope.l, 
                   'time' : $scope.t,
                   'day' : $scope.d,
                   'type' : 'get_restopen' }),
             headers: {'Content-Type': 'application/x-www-form-urlencoded'}
          });

        $scope.getClosed = function () {
          return $http({
            // config
          });

        // private functions
        function init(){
             var promises = [];

             promises.push($scope.getOpen());
             promises.push($scope.getClosed());

             $q.all(promises).then(function(datas){
                  // Here, you know both calls have been successfull
                  // datas[0] is the result of $scope.open()
                  $scope.open = datas[0].data;
                  $scope.complete = true;

             }, function(errors){
                  $scope.complete = true;
                  // You fall here if one of your calls has failed
             });
        }

    }
]);

【讨论】:

  • 我在哪里声明$scope.complete = true
  • 样式指南的哪个部分将提供比ng-init更好的解决方案
  • @moh.ABK 我在回答的最后做了一个总结
  • @moh.ABK 用于 ng-init,指南中没有任何内容,我直接引用了 angular。
  • 根据您的摘要代码,我在哪里获取从我的 PHP 返回的data?在init()函数还是个别函数?
【解决方案3】:

$http 是异步的,因此您的 2 个调用应该并行执行。如果您确实需要将 2 个函数归结为一个,并且/或者您需要检查所有 $http 请求是否已完成,您可以使用 $q.all Angularjs $q.all

【讨论】:

    猜你喜欢
    • 2013-09-16
    • 2015-02-28
    • 1970-01-01
    • 2018-03-09
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多