2014-12-18 15 views
7

Powiedzmy mam ładowania zmiennej do $ zakresie z $ http:angularjs dyrektywa załadunku przed danymi

$http.get('/teachers/4').success(function(data){ 
    $scope.teacher = data; 
}); 

Mój szablon wykorzystuje te dane:

Teacher: {{teacher.name}} 
<students-view students="teacher.students"></students-view> 

Dyrektywa ta może załadować PRZED nauczyciel kończy ładowanie, ale mój dyrektywa ma kod, który zależy od tablicy teacher.students ładowane:

app.directive('studentsView', function(){ 
    return { 
    scope: { students: '=' }, 
    controller: function($scope){ 
     _.each($scope.students, function(s){ 
     // this is not called if teacher loads after this directive 
     }); 
    } 
    }; 
}); 

Jak to zrobić uzyskać zachowanie, które chcę tutaj? Nie chcę przestać używać $ http i nie chciałbym, jeśli to możliwe, przypisać obietnicy do zakresu.

+0

co się dzieje w pętli? Można umieścić tę pętlę wewnątrz odwołania zwrotnego sukcesu w kontrolerze, jeśli to pomaga lub przenosi całe żądanie do usługi – charlietfl

Odpowiedz

20

Użyj zegarka, aby poczekać, aż students będzie dostępny. Gdy będzie dostępny, wywołaj kod, który zależy od niego, a następnie usuń zegarek. Możesz pominąć usunięcie zegarka, jeśli chcesz, aby kod był wykonywany przy każdej zmianie students.

app.directive('studentsView', function(){ 
    return { 
    scope: { students: '=' }, 
    link: function($scope){ 
     var unwatch = $scope.$watch('students', function(newVal, oldVal){ 
     // or $watchCollection if students is an array 
     if (newVal) { 
      init(); 
      // remove the watcher 
      unwatch(); 
     } 
     }); 

     function init(){ 
     _.each($scope.students, function(s){ 
      // do stuff 
     }); 
     } 
    } 
    }; 
}); 
+0

Jaka jest różnica między umieszczeniem tego kodu w funkcji kontrolera i umieszczeniem go w funkcji łącza? – Dave

+2

@Dave W procesie kompilacji DOM kontrolery dyrektyw otrzymują instancję przed funkcjami łącza, więc funkcje linków mogą zasadniczo być widoczne na poziomie końcowym/stabilnym. Dokumenty Angular zalecają użycie [_controller, gdy chcesz udostępnić interfejs API innym dyrektywom. W przeciwnym razie użyj linku] (https://docs.angularjs.org/guide/directive#summary) _. Niektórzy twierdzą inaczej: [Różnica między funkcjami "kontrolera", "łącza" i "kompilacji" podczas definiowania dyrektywy] (http://stackoverflow.com/a/12570008/2943490). To zależy od tego, czy powyższe zamówienie ma znaczenie dla twojego przypadku użycia. – user2943490

1

Prawdopodobnie będziesz musiał zrobić jakiś zegarek na students wiedzieć, kiedy jest ona aktualizowana, a następnie uruchomić _.each gdy zegarek jest wyzwalany:

app.directive('studentsView', function(){ 
    return { 
    scope: { students: '=' }, 
    controller: function($scope){ 
     scope.$watch('students', function(newValue, oldValue) { 
     _.each($scope.students, function(s){ 
      // this is not called if teacher loads after this directive 
     });  
     }; 
    } 
    }; 
}); 

Więcej na $watch: https://docs.angularjs.org/api/ng/type/$rootScope.Scope

Powiązane problemy