【问题标题】:How to access object outside the promised function in angularjs如何在angularjs中访问承诺函数之外的对象
【发布时间】:2018-05-09 05:33:12
【问题描述】:

我是 angularjs 的新手,作为初学者,我在访问 then 函数之外的对象时遇到问题。我创建了一个工厂:

    var injectParams = ['$http'];
    var address = function ($http) {
    var factory = {};

    factory.get = function () {
        return $http({
            method: "POST",
            url: '/address',
            headers: {
                'Content-Type': 'application/json'
            },
            data: {
                service: 'address'
            }
        });
    };
  return factory;
 }

还有一个控制器方法:

   function getAddresses() {
        address_factory.get().then(function success(response) {
            $scope.billing = response.data.billing;
            $scope.shipping = response.data.shipping;
            console.log(response.data);

        }, function error(x) {
            console.log(x);
        });
    }
   getAddresses();

问题是我如何在getAddresses 函数之外访问$scope.billing 对象?我已经阅读了 angularjs 中的承诺,但我不明白如何使用...

【问题讨论】:

    标签: javascript angularjs promise angularjs-scope


    【解决方案1】:

    $scope 变量在控制器中的任何地方都可以在 Promise 之外使用...

    因此 $scope.billing 可以在 html 和控制器 js 中访问...

    【讨论】:

    • 这是什么意思...'因此 $scope.billing 将在 html 和控制器 js 中都可以访问'?当我尝试输出 $scope.billing 或在 getAddresses 函数之外查找此对象的长度时,结果为空。 console.log($scope.billing);我的意思是我知道在 html 中我可以访问对象但想在控制器中访问。
    • 这是因为promise在事件循环中并且你在事件循环返回之前访问..尝试在$timeout中使用它
    • @Danish 不,不要使用$timeout。当值可用时,在 promise 上使用 then 回调来运行代码。
    【解决方案2】:

    $scope.billing 在控制器和绑定到该控制器的模板中随处可访问。但是$scope.billing 的值是动态的,它是undefined,直到解决了 factory-get Promise。要在模板中反映 $scope.billing 的动态特性,您可以尝试以下方法:

     function getAddresses() {
        $scope.loading = true;
        address_factory.get().then(function success(response) {
          $scope.billing = response.data.billing;
          $scope.loading = false;
          $scope.error = null;
        }, function error() {
          $scope.loading = false;
          $scope.error = true;
        });
      }
     getAddresses();
    

    然后在模板中:

    <div ng-if="loading">
      Loading...
    </div>
    <div ng-if="!loading && error">
      Got an error!
    </div>
    <div ng-if="!loading && !error">
      Billing: {{billing}}
    </div>
    

    另外,您可以在控制器中使用$scope.$watch 来观察$scope.billing 的变化:

    // ...
    getAddresses();
    
    $scope.$watch('billing', function() {
      // $scope.billing has been changed
      console.log($scope.billing);
    });
    

    但我建议在 Promise.then 调用的成功回调中执行所有必要的逻辑。

    【讨论】:

    • 是的,你是对的。我理解发生这种情况的原因。你有任何模式建议如何解决它。'修复它'我的意思是如何在成功回调中使用必要的逻辑?
    • @MrAlb 没有什么可修复的,这就是 Promise 的工作方式,所以只需将您的逻辑放在手表回调或 address_factory.get 成功回调中(我更喜欢第二个选项) .另外,如果你对 ES2017 没问题,你可以试试async-await 语法,让代码更像同步。
    • 也许我解释得不好。我在同一个控制器中创建了另一个分页功能。想法是,我想找到 $scope.billing 对象的长度,所以我可以在分页中使用功能。我了解承诺的工作原理,但如果找不到这个对象的长度,我无法进行分页。很抱歉,我花了你的时间。
    • @MrAlb 仅在解决 Promise 时处理分页。您可以通过loading 方法阻止模板中的分页。你可以在 billing-watch 回调或 address_factory.get 成功回调中初始化你的分页逻辑。如果您仍然有问题,我建议您发布一个新问题,其中包含与分页案例相关的更多详细信息。
    【解决方案3】:

    $scope 表示当前范围,即当前可以访问 some-controller.jssome-view.html 的区域.

    如果您将任何变量设置为 $scope,它将可以在 some-controller.js 和 some-view.html 中的任何位置访问。

    假设您将 ng-controller 设置为 &lt;div ng-controller="SomeController"&gt;.....&lt;/div&gt; 的任何 div。所以任何像 $scope.something 在控制器中设置的 $scope 的东西都可以在控制器中访问,并且也可以在这个 div 中访问,因为控制器的范围是 this。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 2016-04-05
      • 1970-01-01
      • 2020-02-07
      相关资源
      最近更新 更多