【问题标题】:Angularjs $rootScope:infdig Error calling http in view methodAngularjs $rootScope:infdig 在视图方法中调用 http 时出错
【发布时间】:2018-12-20 12:31:41
【问题描述】:

我正在尝试从 AngularJS 应用程序的 html 页面中的服务器获取一些信息。但是,当我使用 $scope 在我的 html 文件中调用该函数时,该方法本身工作正常。我收到 $rootScope:infidg 错误。

控制器中的方法:

    $scope.getTranslation = function(){
        $http.get('https://producthero.com/index.php?option=com_hero&task=language.translate&s=SEARCH')
            .then(
                function (response) {
                    return response.data.translation;
                }
            );
    };

使用 ng-app 和 ng-controller 调用 html 文件:

<div ng-controller="Product">
    <span>{{getTranslation()}}</span>
</div>

我使用这种翻译方式是因为网站的初始后端是在 Joomla 中运行的,我知道 i18n,但我们不能在这里使用它。

错误是:

http://errors.angularjs.org/1.6.4/$rootScope/infdig?p0=10&p1=%5B%5D

angular.min.js:123 Error: [$rootScope:infdig] <http://errors.angularjs.org/1.6.4/$rootScope/infdig?p0=10&p1=%5B%5D>
    at angular.min.js:6
    at m.$digest (angular.min.js:147)
    at m.$apply (angular.min.js:149)
    at angular.min.js:21
    at Object.invoke (angular.min.js:44)
    at c (angular.min.js:21)
    at Sc (angular.min.js:22)
    at ue (angular.min.js:20)
    at HTMLDocument.<anonymous> (angular.min.js:331)
    at i (jquery.min.js:2)

我希望这只是我的愚蠢,我错过了一些东西来使这种通过 http 直接调用成为可能!

编辑:

我的翻译问题的解决方案如下(感谢@Aleksey Solovey 的回答):

控制器方法

$scope.translations = {};

$scope.getTranslation = function(string){
    $http.get('https://producthero.com/index.php?option=com_hero&task=language.translate&s=' + string)
        .then(
            function (response) {
                $scope.translations[string] = response.data.translation;
            });
    };

查看通话

<div ng-app="products">

        <div ng-controller="Product">
            <span ng-init="getTranslation('SEARCH')">{{translations.SEARCH}}</span>
    </div>
</div>

【问题讨论】:

标签: angularjs angularjs-scope angularjs-http


【解决方案1】:

您能否给出一个不同的答案,提供一个不使用 ng-init 的示例?

只需在控制器中手动初始化即可:

app.controller('Product', function($scope, $http) {
  $scope.getTranslation = function() {
    $http.get('https://producthero.com/index.php?option=com_hero&task=language.translate&s=SEARCH').
    then(function(response) {
      $scope.translation = response.data.translation;
    });
  };
  //INSTEAD OF ng-init
  $scope.getTranslation();
});
<div ng-app="myApp">
  <div ng-controller="Product">
    ̶<̶s̶p̶a̶n̶ ̶n̶g̶-̶i̶n̶i̶t̶=̶"̶g̶e̶t̶T̶r̶a̶n̶s̶l̶a̶t̶i̶o̶n̶(̶)̶"̶>̶{̶{̶t̶r̶a̶n̶s̶l̶a̶t̶i̶o̶n̶}̶}̶<̶/̶s̶p̶a̶n̶>̶
    <span>{{translation}}</span>
  </div>
</div>

ng-init 指令可能会被滥用以在您的模板中添加不必要的逻辑量。 ngInit 只有几个合适的用途。见AngularJS ng-init API Reference


出于性能原因,应避免在带有{{ }} 的 HTML 插值绑定中使用函数。这些函数在每个摘要循环中被调用一次或多次。

错误

<div ng-controller="Product">
    <span>{{getTranslation()}}</span>
</div>

返回 Promise 的异步函数会导致无限摘要错误。

有关详细信息,请参阅

【讨论】:

  • 啊,我明白你的意思了!但是我需要在产品列表等上使用 ng-repeat 即时进行很多翻译。这就是为什么我希望它在视图中生成,尽管它似乎不是最好的解决方案!谢谢你的回答
  • 有一些方法可以在ng-repeat 中避免ng-init。它涉及链接承诺和使用$q.all。它避免了模型和视图的纠结。结果是代码更易于理解、调试、测试和维护。
  • 我也会去看看。感谢您提供所有信息!
【解决方案2】:

$http 请求会返回一个 Promise,而不是某个值。因此,您需要先填充一个作用域变量,然后(异步)使用它。它应该是这样的:

var app = angular.module('myApp', []);
app.controller('Product', function($scope, $http) {
  $scope.getTranslation = function() {
    $http.get('https://producthero.com/index.php?option=com_hero&task=language.translate&s=SEARCH').
    then(function(response) {
      $scope.translation = response.data.translation;
    });
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="Product">
    <span ng-init="getTranslation()">{{translation}}</span>
  </div>
</div>

【讨论】:

  • 啊,听起来很合乎逻辑。谢谢,这工作得很好!
  • ng-init 指令可能会被滥用以在模板中添加不必要的逻辑量。 ngInit 只有少数合适的用法。见AngularJS ng-init API Reference
  • 您能否给出一个不同的答案,提供一个不使用 ng-init 的示例?如果有更干净、强度更低的解决方案,我很高兴收到您的来信@georgeawg
  • @DavidKooijman 'init' 用于初始化,只需在控制器中使用$scope.getTranslation()手动初始化即可
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多