Obtener el valor de 3 select de diferentes controladores en un controlador principal
Tengo una duda en lo siguiente:
Hice 2 archivos en plunker, en el siguiente link para un ejemplo mas claro
http://plnkr.co/edit/CA2D5RDvZeBQLnMUXFOH?p=preview
Los select
<body ng-app="MyForm"> <div id="container" ng-controller="mainController"> <!-- comment --> <div ng-controller="programsController"> <select name="program" id="program" ng-model="program" ng-options="prog.name for prog in programs"> </select> RES {{program.name}} DOS {{selected_program}} </div> <!-- comment --> <div ng-controller="periodsController"> <select name="period" id="period" ng-model="period" ng-options="period.name for period in periods"> </select> </div> <!-- comment --> <div ng-controller="teacherController"> <select name="teacher" id="teacher" ng-model="teacher" ng-options="teacher.name for teacher in teachers"> </select> </div> <button ng-click="vals()">Click</button> </div>El modulo principal es MyForm
angular.module('MyForm',['Programs','Periods','Teachers']) .factory('myFactory', function() { console.log('Factory loaded'); var course = { program : 'no set', setValues : function (program){ course.program=program; }, sayHello : function(){ alert('hello'); } } console.log(course); return course; }) .controller('mainController',['$scope','myFactory',function($scope,myFactory){ $scope.vals = function(){ //myFactory.setValues(myFactory.program); //myFactory.sayHello(); alert('The values are:' + '\nProgram: ' + myFactory.program + '\nProgram: ' + myFactory.period + '\nProgram: ' + myFactory.teacher); } }]) ;
Los modulos Programs, Periods y Teachers son utilizados para los selects. Los hice en modulos porque esos mismos selects van a ser reutilizados en otras paginas y para evitar repeticion de codigo.
Otra forma que se me ocurre es repetir el codigo de cada controlador e incluirlo en un solo controlador para asi acceder al scope desde un solo controlador.
angular.module('Programs',[]) .factory('proFactory',function(){ var selected_program = '0'; console.log('From proFactory'); }) .controller('programsController',function($scope,myFactory){ $scope.programs=[ {ID:1 , name:'HTML'}, {ID:2 , name: 'AngularJS'} ]; $scope.program = $scope.programs[0]; //myFactory.setValues($scope.program.ID); }); angular.module('Periods',[]) .controller('periodsController',function($scope){ $scope.periods=[ {ID:1 , name:'Jan-Feb'}, {ID:2 , name: 'Mar-Apr'} ]; $scope.period = $scope.periods[0]; }); angular.module('Teachers',[]) .controller('teacherController',function($scope){ $scope.teachers=[ {ID:1 , name:'Mark Smith'}, {ID:2 , name: 'Joe Cliff'} ]; $scope.teacher = $scope.teachers[0]; });
El boton del html ejecuta la funcion vals() que esta en el scope del mainController, sin embargo he intentado varias maneras de asignar los valores de los selects a alguna variable.
<button ng-click="vals()">Click</button>
Leyendo encontre que para esto, es decir compartir o acceder a variables fuera del scope del controlador, hay que utilizar un provider, en este caso lo estoy intentado con un factory, y en el factory devolver un objeto que tenga los metodos (API) para asignar el valor a las variables, sin embargo aqui es donde estoy estancado.
angular.module('Programs',[]) .factory('proFactory',function(){ var selected_program = '0'; console.log('From proFactory'); return { set_program: (function(program){ selected_program = program; }), get_program: (function(){ return selected_program; }), sayHi : (function(){alert('hi from proFactory');}) }; })
¿Alguna idea para asignar los valores de los selects a alguna variable u objeto y mostrarlos en un alert o en la consola desde el mainController?
Gracias de antemano.
Tienes algunas opciones para solucionar este problema, te voy a comentar dos y tu decide cual te conviene más.
En primer lugar puedes indicarle en el modelo del input que la propiedad corresponderá al scope del controlador padre, eso lo haces mediante el objeto $parent de la siguiente manera.
<select name="program" id="program" ng-model="$parent.program" ng-options="prog.name for prog in programs"> </select>
Con eso la propiedad program se va a crear en el scope del main controller, permitiendo acceder a ella así.
.controller('mainController',['$scope','myFactory',function($scope,myFactory){ var me = this; $scope.vals = function(){ $scope.program.name //<---- } });
La segunda opción es usar un alias para el controlador, de esta manera en el modelo del input especificas donde se creará la propiedad, por ejemplo.
<div id="container" ng-controller="mainController as main"> <!-- comment --> <div ng-controller="periodsController"> <select name="period" id="period" ng-model="main.period" ng-options="period.name for period in periods"> </select> </div> </div>
Donde se declara el controler se crea un alias, en este caso main, luego en el ng-model usamos ese alias, de esa manera la propiedad period se va a crear dentro del controller, para accederla sería algo así:
.controller('mainController',['$scope','myFactory',function($scope,myFactory){ var me = this; $scope.vals = function(){ me.period.name //<----- } });
Algo importante por mencionar es que la propiedad se crea directamente dentro de la instancia del controlador y no dentro del objeto scope.
Existe una técnica más llamada dot rule, si quieres luego te la explico, por el momento revisa los dos ejemplos que te puse y decide cual te conviene más, te dejo el link a JSBin para que veas el ejemplo funcionando.
http://jsbin.com/wehabuzuyo/1/edit?html,js,outputSaludos!
¿Conoces a alguien que pueda responder esta pregunta? Comparte el link en Twitter o Facebook
Es necesario registrarse para poder participar en el foro! Si ya tienes una cuenta puedes entrar y comentar en este foro.