2013-07-04 2 views
11

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

<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

Вот plunker играть с http://plnkr.co/7BriYDbdVJvIoIigQcTU

+0

Да, я думаю, это, вероятно, объясняет это, спасибо. Однако метод getValueAsync в моем примере всегда возвращает одно и то же значение, поэтому я не могу понять, почему Angular сочтет нужным продолжать его на неопределенное время. –

ответ

16

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

$ HTTP сервис запускает $rootScope.$apply()when requests are completed и так $apply запускает $ переваривать цикл это делает ваше выражение вида быть переоценены, который в свою очередь вызывает ваши функции асинхронной называться снова, и так далее ...

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> 

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

+0

Спасибо. Это кажется довольно эзотерическим - даже неинтуитивным - поведением, хотя я могу, возможно, понять, почему это необходимо, учитывая требование Angular о славе для двусторонней привязки. –

+0

Еще один комментарий, руководство, которое вы даете эффективно, означает, что взгляды никогда не должны быть связаны с функциями, если функции используют обещания внутри. Это действительно заслуживает внимания в Angular docs. –

+1

На самом деле, я бы пошел дальше! $ http.get() - классическая функция и не должна иметь побочных эффектов, таких как это. -1 для углового. –

0

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

Смежные вопросы