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.
