Comment transmettre des données à un contrôleur ng-include?

J'ai un élément html ng-include et je souhaite passer certaines données de l'extérieur vers le contrôleur.

Le controller principal fetches data json partir d'un service http webservice et extrait les données dans la variable climadata variable.

Voici le pseudocode , mais vous avez l'idée:

 function mainController($scope, $http) { $http.get().then( $scope.climadata = response.clima; ); } <div ng-controller="mainController"> <div ng-include="'clima.html'" ng-controller="climaController" onload="climamodel = climadata"></div> </div> 

Cela fonctionne bien, MAIS le climadata n'atteint jamais le climaController . Vérifié comme suit:

 function climateController($scope) { console.log($scope.climamodel); //prints "undefinied" }; 

Le climamodel est toujours indéfini dans la console, mais pourquoi?

Cela fonctionne, la raison pour laquelle vous obtenez le undefined est parce que, vous obtenez les données par $http requête en $http , pour cela, avant que vous obteniez les données que climaController exécute, à ce moment-là, il n'y a pas de portée variable appel climadata .

Vérifiez cette DEMO

Vous pouvez voir la console imprimer undefined mais vous obtiendrez les données sur la page HTML partielle après la disponibilité des données après la demande ajax.

Si vous souhaitez charger l' inclcude après l' inclcude de l'ajax, utilisez ng-if

 <div ng-if="climadata" ng-include="'clima.html'" ng-controller="climaController"></div> 

Si climadata est présent, alors seul ce processus div, qui signifie include travaux uniquement si climadata est disponible.

DEMO

Et vous pouvez annuler de onload="climamodel = climadata"

Essaye ça:

  function mainController($scope, $http) { $scope.data={}; $http.get().then( $scope.data.climadata = response.clima; ); } <div ng-controller="mainController"> <div ng-include="clima.html" ng-controller="climaController">/div> </div> 

Je pense que la meilleure façon serait d'utiliser $broadcast

Il s'agit essentiellement d'un service pour propager des événements sur des gammes enfants (lire: contrôleurs enfants). Les contrôleurs enfants écoutent l'événement de $broadcast utilisant $on service $on service.

Voici comment vous pouvez l'implémenter. Dans votre MainController :

 function mainController($scope, $http, $broadcast) { //injected broadcast $http.get().then( $scope.climadata = response.clima; $scope.$broadcast('climaData', $scope.climadata); //broadcast event 'climaData' and send '$scope.climadata' as argument. ); } 

Dans votre climatController :

 function climateController($scope) { $scope.$on('climaData', function(event, args) { //listener for 'climaData' event. console.log(args); //args contains $scope.climadata sent from the main controller. }) }; 
  • Tout d'abord, vous devez changer la ng-load en ng-load ou ng-init . Car la onload ne peut pas lire les propriétés angulaires.

  • Vous pouvez utiliser $rootScope , il est utile de passer des valeurs d'un contrôleur à un autre contrôleur.

function climateController($rootScope ) { console.log($rootScope.climamodel); };

Vous trouverez également d'autres détails: AngularJS: Comment puis-je passer des variables entre les contrôleurs?

Je pense que le partage des données par l'héritage de la portée crée un code spaghetti. Il faut inspecter votre code et votre modèle pour comprendre ce qui se passe.

Pour votre problème, je créerais un service qui va charger et mettre en cache des données. Ce service pourrait être injecté aux deux contrôleurs.

Voici un exemple de code

 module.factory('UserService', ['$http', '$q', function($http, $q){ var userAPI = {}; var userData = null; var isLoading = false; userAPI.getMyData = function(){ var deferred = $q.defer(); if(userData != null){ deferred.resolve(userData); } else if(isLoading === false) { isLoading = true; $http.get('/api/data/data').then(function(resp){ userData = resp.data; deferred.resolve(userData); }, function(err){ deferred.reject(err); }); } return deferred.promise; }; return userAPI; }]);