Подтвердить что ты не робот

Бесконечный цикл с привязкой выражения Angular

У меня есть приложение angular, которое отображает значение, возвращаемое методом контроллера, посредством простого привязки выражения:

<div>{{getValue()}}</div>

Если рассматриваемый метод просто возвращает значение, метод вызывается дважды, и это довольно странно:

$scope.getValue = function(){
  return 'some value';
}

Но если метод выполняет некоторую асинхронную работу, такую ​​как получение файла с сервера, код переходит в бесконечный цикл:

$scope.getValueAsync = function(){
  $http.get('myfile.html')
    .success(function (data, status, headers, config) {
      return 'some async value';
    });

  return 'file not found'; // same value returned every time but $digest cycle still loops
}

Я новичок в angular, поэтому, возможно, пропустил что-то основное здесь, но может кто-нибудь объяснить, что происходит?

Plunker

Здесь плукер, чтобы играть с http://plnkr.co/7BriYDbdVJvIoIigQcTU

4b9b3361

Ответ 1

Несмотря на то, что ваша функция async возвращает ту же самую точную строку каждый раз, цикл $digest запускается в циклах, потому что ваша функция также делает вызов ajax с помощью службы $http.

$http триггеров службы $rootScope.$apply() когда запросы завершены, и поскольку $apply запускает цикл $digest, это делает ваше выражение выражения переопределенная, которая в свою очередь заставляет вашу функцию асинхронного вызова снова называться и так далее...

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

  $scope.getValue = function(){
    return 'some value';
  }

  $scope.getValueAsync = function(){
    $http.get('myfile.html')
      .success(function (data, status, headers, config) {
        return 'some async value';
      });

    return 'file not found';
  }
});
<div>{{getValueAsync()}}</div>

Мораль истории. Если вы используете функции в выражениях, убедитесь, что ваши функции не влияют на что-то вне их, которое вызовет цикл $digest, и убедитесь, что ваши функции всегда возвращают такой же выход, учитывая тот же ввод.

Ответ 2

Я встретил ту же проблему, что и вы, чтобы исправить проблему, мы можем кэшировать результаты функции. Для этой цели я предпочитаю использовать функцию memoize Lo-Dash. Я создаю демоверсию, чтобы показать вам, как мне удалось исправить эту проблему. The following link contains the demo: http://plnkr.co/edit/KBmk4J2ZCt0SsmZlnKZi?p=preview