2013-07-04 28 views
11

mam kątową aplikacji, która wyświetla wartość zwracana przez metodę kontrolera za pomocą prostego wyrażenia Oprawa:Nieskończona pętla z Kątowymi wyrażenia wiążącego

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

Jeśli omawiana metoda po prostu zwraca wartość, metoda nazywa dwa razy, i to jest dosyć dziwne:

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

Ale jeśli metoda ma pewne asynchroniczną pracę takich jak dostaję plik z serwera, kod przechodzi w nieskończonej pętli:

$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 
} 

Jestem nowy w Angular, więc pewnie przegapiłem coś podstawowego, ale czy ktoś może wyjaśnić, co się dzieje?

Plunker

Oto plunker grać z http://plnkr.co/7BriYDbdVJvIoIigQcTU

+0

Tak, myślę, że prawdopodobnie to wyjaśnia, dzięki. Jednak metoda getValueAsync w moim przykładzie zawsze zwraca tę samą wartość, więc nie widzę powodu, dla którego Angular uznałby za stosowne kontynuowanie wywoływania go w nieskończoność. –

Odpowiedz

16

Nawet jeśli funkcja asynchronicznego zwraca ten sam łańcuch znaków za każdym razem, zmienna $ strawić cyklu jest zwolniony w pętli, ponieważ funkcja sprawia również ajax zadzwoń za pomocą usługi $ http.

usługa $ http wyzwala $rootScope.$apply()when requests are completed a od $apply wyzwala cykl $ strawić to sprawia, że ​​widok wyrażenie zostać ponownie ocenione, który w zamian powoduje czynność asynchroniczny nazywać ponownie, i tak dalej ...

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> 

Morał z tej historii: w przypadku korzystania z funkcji w wyrażeniach, upewnij się, że funkcje nie wpływają coś poza nimi, które wyzwoli pętlę $ strawić i upewnić się, że działa zawsze zwraca ten sam wyjście z tym samym wejściem.

+0

Dzięki. To wydaje się dość ezoteryczne - nawet nieintuicyjne - zachowanie, choć może widzę, dlaczego jest to konieczne, biorąc pod uwagę roszczenia Angulara do sławy dwukierunkowego wiązania. –

+0

Jeszcze jedna uwaga, wskazówka, którą dajesz skutecznie oznacza, że ​​widoki nigdy nie powinny być związane z funkcjami, jeśli funkcje wykorzystują obietnice wewnętrznie. To naprawdę zasługuje na nacisk w kątowych dokumentach. –

+1

W rzeczywistości, pójdę dalej! Funkcja $ http.get() jest klasyczną funkcją i nie powinna mieć efektów ubocznych takich jak ta. -1 dla Angular. –

0

Spotkałem ten sam problem, co Ty, aby naprawić problem, możemy buforować wyniki funkcji. W tym celu wolę używać funkcji memoize Lo-Dasha. Tworzę demo, aby pokazać, jak udało mi się rozwiązać ten problem. The following link contains the demo:http://plnkr.co/edit/KBmk4J2ZCt0SsmZlnKZi?p=preview

Powiązane problemy