2015-10-23 2 views
3

У меня есть элемент html ng-include, и вы хотите передать некоторые данные извне в контроллер.Как передать данные контроллеру ng-include?

Основной controllerfetchesjsondata из http webservice, и извлекает данные в Scoped переменной climadata.

Ниже pseudocode, но вы получите идею:

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> 

Это прекрасно работает, НО climadata никогда не достигает climaController. Проверено следующим образом:

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

Климамодель всегда не определена в консоли, но почему?

+1

Вы можете использовать сервис для обмена данных .. – Rayon

+0

Не возможно без введения услуги просто передав modeldata туда и обратно? – membersound

+1

normaly, вы ничего не делаете, чтобы получить климамодель от mainController, потому что это контрольный родитель климатконтроля. – hic1086

ответ

6

Это работает, причина, вы получение undefined потому, что вы получите данные по $http запросу, из-за того, что , прежде чем вы получите данные climaController, то в этот момент не будет вызова переменной области climadata.

проверить это DEMO

вы можете увидеть консоль печати undefined, но вы получите данные о частичной HTML странице после того, как данные доступны после запроса Ajax.

Если вы хотите загрузить inclcude после Аякса завершения затем использовать ng-if

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

если climadata присутствует, то только этот процесс DIV означает, что include работает только если climadata доступен.

DEMO

и вы можете аннулирование от onload="climamodel = climadata"

+0

Я думаю, что это главная причина +1. Но я не испытал это. –

+0

Это потрясающе. – membersound

0
  • Прежде всего, необходимо изменить onload к ng-load или ng-init. потому что onload не может прочитать угловые свойства.

  • Вы можете использовать $rootScope, Это помогает передавать значение от контроллера к другому контроллеру.

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

Кроме того, некоторые другие детали, вы можете получить здесь: AngularJS: How can I pass variables between controllers?

+0

Это также дает мне «undefined». – membersound

+0

@membersound, назначили ли вы 'climamodel'' rootcope'? – Rayon

+0

Нет, просто для нормалей '$ scope'. – membersound

0

Попробуйте это:

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> 
+0

Я все еще получаю 'undefined' для' console.log ($ scope.data.climadata) 'в' climaController'. – membersound

+0

вам нужно сделать console.log, когда $ http.get доставляет ответ. – hic1086

0

Я думаю, что лучше всего было бы использовать $broadcast

Это, по сути, служба для распространения событий на дочерние области (чтение: дочерние контроллеры). Контроллеры-дочерние устройства прослушивают событие $broadcast, используя услугу $on.

Вот как вы можете его реализовать. В вашей 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. 
    ); 
} 

В вашей climateController:

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

я думаю, что обмен данных через наследование области видимости создает код спагетти. Вы должны проверить свой код и шаблон, чтобы понять, что происходит.

Для вашей проблемы я бы создал службу, которая будет загружать и кэшировать данные. Эта услуга может быть введена для обоих контроллеров.

здесь приведен пример код

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; 
}]); 
Смежные вопросы