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
enng-load
oung-init
. Car laonload
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; }]);