2013-03-19 18 views
5

Czy istnieje jakiś rzekomy problem z następującym fragmencie:angularjs obserwując wynik wywołania funkcji

<ul id="entry-name" class="breadcrumb"> 
     <li ng-repeat="dir in pathElements()" class="active"> 
      <span ng-show="!$last"> 
       &nbsp;<a href="#!?path={{dir.url}}">{{ dir.name }}</a>&nbsp;<span ng-show="!$first" class="dividier">/</span> 
      </span> 
     </li> 
     <li class="active">{{ pathElements()[pathElements().length - 1].name }}</li> 
    </ul> 

z tym JS:

$scope.pathElements = function() { 
     var retval = []; 
     var arr = $scope.currentPath().split('/'); 
     if (arr[0] == '') { 
      arr[0] = '/'; 
     } 

     var url = "/"; 
     retval.push({name: arr[0], url: url}); 
     for (var i = 1; i < arr.length; ++i) { 
      if (arr[i] != '') { 
       url += arr[i] + '/'; 
       retval.push({name: arr[i], url: url}); 
      } 
     } 
     return retval; 
    }; 

Wydaje się to być przyczyną „Błąd: Osiągnięto 10 $ digest() iteracji. błąd, ale nie jestem pewien dlaczego. Czy to dlatego, że pathElements() zwraca za każdym razem nową tablicę? Czy istnieje sposób na obejście tego?

+0

Czy uważasz, że nie ma sensu buforowanie tablicy ścieżek? Wywołujesz tę funkcję 3 razy. Poza tym, czy myślałeś o użyciu $ routeParams? –

+0

@Flek "Ścieżka", którą dzielę nie jest faktyczną ścieżką URL, jest to parametr przekazywany do adresu URL (np. 'Localhost: 8000/#? Ścieżka =/część/ścieżka') Ale tak, ty ' re prawo, prawdopodobnie powinno być buforowanie go. – Alec

Odpowiedz

4

Tak, dzieje się tak, ponieważ za każdym razem zwracasz nową tablicę, a pętla $ digest nieskończenie pętli (ale Angular ją przerywa). Powinieneś zadeklarować go poza funkcją.

$scope.pathArray = []; 
$scope.pathElements = function() { 
    // retval becomes $scope.pathArray 
    if (weNeedToRecalcAllPathVariables) { 
    $scope.pathArray.length = 0; 
    // ... 
    } 

    // ... 
} 

Używamy $scope.pathArray.length = 0 zamiast tworzyć nowe, aby uniknąć ciągłego ostrzału.

Powinieneś także rozważyć sugestie @Flek. Wywołaj tę funkcję tylko raz, w czasie, w którym będzie ona potrzebna do ponownego przeliczenia. A wszystko, co wiążesz, powinno być bezpośrednio nad $scope.pathArray.

Jeśli potrzebujesz funkcji do przetestowania stanu sklejenia przed jej użyciem, to przynajmniej proponuję utworzyć dwie osobne funkcje, aby zachować każdą funkcję z własnym atrybutem.

+0

OK, to ma dużo więcej sensu, ale teraz po prostu nie wiem, jak sprawdzić, kiedy zaktualizować 'pathArray'. "Ścieżka", którą uzyskuję, pochodzi z parametru adresu URL (konkretnie '$ location.search(). Ścieżka'). Czy mogę bezpiecznie "$ watch" tego wyrażenia? – Alec

+0

Tak, możesz. Ale będziesz musiał obejrzeć funkcję, która zwraca wskazaną wartość: '$ scope. $ Watch (function() {return $ location.search(). Path;}, function pathChanged (newValue) {});' as there is nie ma możliwości bezpośredniego powiązania z usługami. –

Powiązane problemy