Angular(1)和$ scope和异步请求

时间:2016-09-10 20:13:50

标签: javascript angularjs

我仍然是Angular(1)的新手并且确实持续存在范围问题。这可能很容易解决,但我似乎无法弄清楚自己并继续努力保持我的$范围更新。

说我有以下代码

.controller('PostsCtrl', function ($scope, $http, $timeout, PostService) {
    $scope.items = [];

    PostService.getAll().then(function(data) {
        var remoteItems = data;

        for (var i = 0; i < remoteItems.length; i++) {
            var object = {};
            object.title = remoteItems[i].title;
            object.id = remoteItems[i]._id;
            $scope.items.push(object);
        }
    });
}) 

正如您所看到的,我已经创建了一个小服务,它确实向我的后端提出了实际请求。我使用promise并提供回调函数。

现在,因为我在回调中更新$scope.items,因为范围不同,它不会更新控制器内的$ scope。

在我的浏览器的JavaScript控制台中添加$scope.$apply时,我收到$digest already in progress错误消息。这应该通过将apply函数包装在$timeout函数中来解决。这解决了错误消息,但没有给我所需的输出。我读到当我收到这些$digest already in progress错误消息时,我的应用程序的体系结构是错误的,但我找不到应该如何更改我的体系结构来解决这个问题。

我该如何解决这个问题?或者更好地说,解决这个问题的最佳做法是什么?我觉得这在大多数Angular应用程序中都会发生很多事情:)。

我创建了一个类似于我的代码的Plunker,虽然我不知道如何解决$ http请求...链接到这里:https://plnkr.co/edit/rhWhgCgfV0kA1frM41xL

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

PostService.getAll().then(function(data) {
    var remoteItems = data;
    var returnedData = [];
    for (var i = 0; i < remoteItems.length; i++) {
        var object = {};
        object.title = remoteItems[i].title;
        object.id = remoteItems[i]._id;
        returnedData.push(object);
    }
    $scope.$apply(function() {
      $scope.items = returnedData;
    });
});

答案 1 :(得分:0)

您可以使用safeApply来避免&#34; $摘要已在进行中&#34;

宣言:

angular.module('yourApp').run(function ($rootScope) {

   /* safe scope apply to avoid "digest already in"
    * $rootScope.$safeApply(fctA());
    * */
   $rootScope.$safeApply = function () {
      var $scope, fn, arg, force = false, args = arguments;
      if (args.length === 1) {
         arg = args[0];
         if (typeof arg === 'function') {fn = arg;} else { $scope = arg; }
      } else if (args.length > 0) {
         $scope = args[0]; fn = args[1];if (args.length === 3) {force = !!args[2]; }
      }
      $scope = $scope || this || $rootScope;
      if ($scope === window) { $scope = $rootScope; }
      fn = fn || function () {};
      if (force || !($scope.$$phase || $scope.$root.$$phase)) {$scope.$apply ? $scope.$apply(fn) : $scope.apply(fn);} else { fn(); }
   };
})

用法(不要忘记在控制器中注入$rootScope

$rootScope.$safeApply(aFunction());
// or 
$rootScope.safeApply( $scope );

编辑: 看看这个模块也

https://github.com/yearofmoo/AngularJS-Scope.SafeApply

答案 2 :(得分:0)

唉,我感觉很傻,但我发现了这个问题。问题不在于回调功能。 Plunker证明了这一点。我没有重新创建的是部分HTML,我也在我的应用程序中使用。

仔细看看我在主HTML中包含这些部分的位置显示那些超出了我设置控制器的范围。用代码显示:

<div ng-controller="testController">
    <!-- Do things here -->
</div

<!-- Partials go here -->
<div>
</div>

现在是这样的:

<div ng-controller="testController">
    <!-- Do things here -->

     <!-- Partials go here -->
     <div>
     </div>
</div>