【问题标题】:Manually call $scope.$apply raise error on ajax call - Error: [$rootScope:inprog]手动调用 $scope.$apply 在 ajax 调用时引发错误 - 错误:[$rootScope:inprog]
【发布时间】:2016-02-26 07:38:28
【问题描述】:

我尝试使用 Angular Material md-autocomplete,建议列表是通过 Ajax Call 从 Service Host 检索到的。由于延迟响应$scope 变量没有正确更新 UI,它只会在特定控件中发生任何事件时更新。例如 Focus Sent Out 并再次单击 Control,然后它会使用新值更新 UI。

我的确切问题快照发布在md-items is not updating the suggesion list properly in md-autocomplete Angular Material

经过很长时间的google,我得到了一个理论上的解决方案是$scope.$apply() - 参考来自Angular controller scope not updating after jQuery ajax call

但我遇到了一个错误错误:[$rootScope:inprog]...请帮助我如何修复错误

完整的示例源代码:

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl"> 

<p>Person to Select:</p>

<md-autocomplete
          ng-disabled="isDisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text-change="searchTextChange()"
          md-search-text="searchText"
          md-selected-item-change="selectedItemChange(item)"
          md-items="item in Person"
          md-item-text="item.Name"
          md-min-length="0"
          placeholder="Which is your favorite Person?">
        <md-item-template>
          <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.Name}} - {{item.City}}</span>
        </md-item-template>
        <md-not-found>
          No Person matching "{{searchText}}" were found.
        </md-not-found>
      </md-autocomplete>
      <br/>
</div>

<script>
    var app = angular.module('myApp', ['ngMaterial']);

    app.controller('myCtrl', function ($scope, $http, $q) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isDisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            alert("Item Changed");
        }
        $scope.searchTextChange = function () {

            $http({
                method: "GET",
                url: "http://www.w3schools.com/angular/customers_mysql.php",
                params: {
                    uid: $scope.searchText
                }
            })
            .then(function (response) {
                $scope.$apply(function () {
                    $scope.Person = response.data.records;
                });
            });
        }

    });
</script>
</body>
</html>

其实我是使用 localhost 进行 ajax 调用,这里我提到了示例 Ajax URL 是http://www.w3schools.com/angular/customers_mysql.php 供您参考获取数据。

注意:我需要在 Ajax 调用中使用 $scope.$apply() 而不会出现错误错误:[$rootScope:inprog]...

请帮助我...如何解决。

浏览器快照

【问题讨论】:

  • @MartijnWelker 是对的。您的 Question #35624977 是一个异步问题。 (在承诺解决之前不能返回值。)$apply() 不会解决这个问题。
  • @georgeawg 你有什么想法可以解决这个问题吗?
  • 接受@MartijnWelker 的回答并写一个新问题,描述你实际上想要完成的事情,包括期望的行为,你所做工作的总结到目前为止解决问题,并描述您解决问题时遇到的困难。
  • @georgeawg 我正在创建一个新问题。帖子完成后,我会接受他的回答来结束这个问题。
  • @georgeawg 我发布了一个新问题stackoverflow.com/questions/35652828/…,其中描述了问题的详细信息以及我的试错尝试历史记录。

标签: jquery angularjs ajax angularjs-scope


【解决方案1】:

当你使用$函数时,Angular会自动调用$scope.$apply,所以你不必自己调用它,你的UI没有更新的原因一定是在别的地方。

【讨论】:

  • 那么如何更新自动完成列表中的新值呢?在帖子stackoverflow.com/questions/21127709/… - 他们建议手动调用 $scope.$apply() 来更新 UI。
  • 他必须使用 $apply(),因为他使用的是 jQuery 的 $.post,你不必这样做,因为你使用的是 Angular 的 $http
  • 就该具体问题提出一个新问题,并提供详细信息,此问题已得到解答。
  • 请访问stackoverflow.com/questions/35624977/…的帖子,这里我使用实际数据发布了有问题的屏幕截图。
  • @MartijnWelker 是对的。您的 Question #35624977 是一个异步问题。 (在承诺解决之前不能返回值。)$apply() 不会解决这个问题。
【解决方案2】:

如果您需要这样做,请尝试$scope.$applyAsync

文档here

【讨论】:

    【解决方案3】:

    Angular 通常在内部调用 $digest、$watch 来绑定作用域变量。

    在您的情况下,您必须手动调用任何事件侦听器来绑定数据值。

    尝试在你的作用域变量中使用 $watch 或 $apply

    function Ctrl($scope) {
      $scope.messageToUser = "You are done!";
    
        setTimeout(function () {
            $scope.$apply(function () {
                $scope.messageToUser = "Timeout called!";
            });
        }, 2000);
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2015-04-08
    相关资源
    最近更新 更多