2014-12-18 8 views
7

Diciamo che sto caricando una variabile in $ portata con $ http:AngularJS carico di direttiva prima che i dati

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

mio modello utilizza questi dati:

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

Questa direttiva può caricare PRIMA insegnante finisce caricamento, ma la mia direttiva ha codice che dipende dall'array teacher.students che viene caricato:

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 
     }); 
    } 
    }; 
}); 

Come faccio ottenere il comportamento che voglio qui? Non voglio smettere di usare $ http, e vorrei non dover assegnare una promessa all'ambito, se possibile.

+0

cosa sta succedendo nel loop? È possibile inserire quel loop all'interno della callback di successo nel controller se questo aiuta o sposta l'intera richiesta a un servizio – charlietfl

risposta

20

Utilizzare un orologio per attendere che students sia disponibile. Una volta disponibile, chiami il codice che dipende da esso, quindi rimuovi l'orologio. È possibile saltare la rimozione dell'orologio se si desidera che il codice venga eseguito ogni volta students modifiche.

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

Qual è la differenza tra mettere questo codice nella funzione controller e inserirlo nella funzione link? – Dave

+2

@Dave Nel processo di compilazione DOM, i controller di direttività vengono istanziati prima delle funzioni di collegamento, quindi le funzioni di collegamento possono essere viste come agenti sullo stato finale/stabile. I documenti angolari consigliano di utilizzare [_controller quando si desidera esporre un'API ad altre direttive. Altrimenti usa il link] (https://docs.angularjs.org/guide/directive#summary) _. Alcuni discutono diversamente: [Differenza tra le funzioni "controller", "link" e "compile" quando si definisce una direttiva] (http://stackoverflow.com/a/12570008/2943490). Dipende solo dal fatto che l'ordine di cui sopra contenga il tuo caso d'uso. – user2943490

1

Avrete probabilmente bisogno di fare qualche tipo di orologio sul students di sapere quando viene aggiornato, quindi eseguire il _.each quando l'orologio viene attivato:

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 
     });  
     }; 
    } 
    }; 
}); 

Maggiori info su $watch: https://docs.angularjs.org/api/ng/type/$rootScope.Scope

Problemi correlati