简体   繁体   English

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

[英]Angular (1) and $scope and async requests

I'm still quite new to Angular (1) and do keep having $scope issues. 我对Angular(1)还是很陌生,并且确实一直遇到$ scope问题。 It's probably very easy to resolve but I can't seem to figure it out myself and keep struggling to keep my $scope updated. 它可能很容易解决,但是我似乎无法自己弄清楚并一直努力保持$ scope的更新。

Say I've the following code 说我有以下代码

.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);
        }
    });
}) 

As you can see I've created a little service that does make the actual request to my backend. 如您所见,我创建了一个小服务,它向后端发出了实际的请求。 I use a promise and provide a callback function. 我使用promise并提供回调函数。

Now, because I update $scope.items inside the callback, it doesn't update the $scope inside the controller because of different scopes. 现在,由于我在回调内部更新了$scope.items ,因此由于范围不同,它也没有更新控制器内的$ scope。

when adding a $scope.$apply I get $digest already in progress error messages in my browser's JavaScript console. 当添加$scope.$apply $digest already in progress在浏览器的JavaScript控制台中出现了$digest already in progress错误消息。 This should be solved by wrapping the apply function in a $timeout function. 应该通过将apply函数包装在$timeout函数中来解决。 This resolves the error messages but doesn't give me the desired output. 这样可以解决错误消息,但没有给我想要的输出。 I read that when I get these $digest already in progress error messages, the architecture of my application is wrong, though I couldn't find how my architecture should be changed to resolve this. 我读到当我收到这些$digest already in progress错误消息时,我的应用程序体系结构是错误的,尽管我找不到应该如何更改体系结构来解决此问题的方法。

How can I resolve this? 我该如何解决? Or better said, what's the best practice to resolve this? 或者更好的说,解决此问题的最佳实践是什么? I kind of think this is something that happens quite a lot in most Angular applications :) . 我觉得这在大多数Angular应用程序中都会发生很多。

I've created a Plunker that's similar to my code, though I do not know how to work around the $http request... Link here: https://plnkr.co/edit/rhWhgCgfV0kA1frM41xL 我创建了一个类似于我的代码的Plunker,尽管我不知道如何处理$ http请求...链接这里: https : //plnkr.co/edit/rhWhgCgfV0kA1frM41xL

Thanks for your help in advance! 谢谢您的帮助!

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;
    });
});

You can use safeApply to avoid "$digest already in progress" 您可以使用safeApply来避免“ $ digest已经在进行中”

Declaration : 宣言 :

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(); }
   };
})

Usage ( don't forget to inject $rootScope in your controllers ) 用法(不要忘记在控制器中注入$rootScope

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

EDIT : look at this module also 编辑:也看这个模块

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

Ugh, I feel stupid but I found the issue. gh,我觉得很蠢,但发现了问题。 The issue wasn't the callback function. 问题不是回调函数。 The Plunker proved this. 柱塞证明了这一点。 What I didn't recreate was the partial HTML's that I also use in my application. 我没有重新创建的是我还在应用程序中使用的部分HTML。

A closer look on where I included those partials in the main HTML showed that those were out of scope of where I set the controller. 仔细查看我在主HTML中包括那些部分的位置,发现这些部分超出了我设置控制器的范围。 To show with code: 要显示代码:

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

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

Is now this: 现在是这个:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM