modulos - AngularJS accede al ámbito principal desde el controlador secundario
ng attr title (9)
He configurado mis controladores utilizando data-ng-controller="xyzController as vm"
Tengo un escenario con los controladores anidados padre / hijo. No tengo problemas para acceder a las propiedades principales en el html anidado utilizando $parent.vm.property
, pero no puedo averiguar cómo acceder a la propiedad principal desde mi controlador secundario.
He intentado inyectar $ scope y luego usar $scope.$parent.vm.property
, ¿pero esto no funciona?
¿Alguien puede dar consejos?
Acabo de comprobar
$scope.$parent.someProperty
funciona para mi.
y será
{{$parent.someProperty}}
por la vista
Algunas veces es posible que deba actualizar las propiedades principales directamente dentro del ámbito secundario. por ejemplo, debe guardar una fecha y hora de control principal después de los cambios realizados por un controlador secundario. Ej. Código en JSFiddle
HTML
<div ng-app>
<div ng-controller="Parent">
event.date = {{event.date}} <br/>
event.time = {{event.time}} <br/>
<div ng-controller="Child">
event.date = {{event.date}}<br/>
event.time = {{event.time}}<br/>
<br>
event.date: <input ng-model=''event.date''><br>
event.time: <input ng-model=''event.time''><br>
</div>
</div>
JS
function Parent($scope) {
$scope.event = {
date: ''2014/01/1'',
time: ''10:01 AM''
}
}
function Child($scope) {
}
Creo que tuve un dilema similar recientemente
function parentCtrl() {
var pc = this; // pc stands for parent control
pc.foobar = ''SomeVal'';
}
function childCtrl($scope) {
// now how do I get the parent control ''foobar'' variable?
// I used $scope.$parent
var parentFoobarVariableValue = $scope.$parent.pc.foobar;
// that did it
}
Mi configuración fue un poco diferente, pero lo mismo probablemente debería funcionar
Cuando se utiliza as
sintaxis, como ParentController as parentCtrl
, para definir un controlador y luego para acceder a la variable de alcance principal en el uso de controlador ParentController as parentCtrl
, ParentController as parentCtrl
siguiente:
var id = $scope.parentCtrl.id;
Donde parentCtrl
es el nombre del controlador principal que usa as
sintaxis e id
es una variable definida en el mismo controlador.
Desde un componente secundario, puede acceder a las propiedades y métodos del componente principal con ''require''. Aquí hay un ejemplo:
Padre:
.component(''myParent'', mymodule.MyParentComponent)
...
controllerAs: ''vm'',
...
var vm = this;
vm.parentProperty = ''hello from parent'';
Niño:
require: {
myParentCtrl: ''^myParent''
},
controllerAs: ''vm'',
...
var vm = this;
vm.myParentCtrl.parentProperty = ''hello from child'';
Quizás esto sea poco convincente, pero también puede simplemente señalarlos a algún objeto externo:
var cities = [];
function ParentCtrl() {
var vm = this;
vm.cities = cities;
vm.cities[0] = ''Oakland'';
}
function ChildCtrl($scope) {
var vm = this;
vm.cities = cities;
}
El beneficio aquí es que las ediciones en ChildCtrl ahora se propagan a los datos en el padre.
Súper fácil y funciona, pero no estoy seguro de por qué ....
angular.module(''testing'')
.directive(''details'', function () {
return {
templateUrl: ''components/details.template.html'',
restrict: ''E'',
controller: function ($scope) {
$scope.details=$scope.details; <=== can see the parent details doing this
}
};
});
Si tu HTML es como el siguiente, podrías hacer algo como esto:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
A continuación, puede acceder al ámbito principal de la siguiente manera
function ParentCtrl($scope) {
$scope.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentcities = $scope.$parent.cities;
}
Si desea acceder a un controlador principal desde su vista, debe hacer algo como esto:
<div ng-controller="xyzController as vm">
{{$parent.property}}
</div>
Ver jsFiddle: http://jsfiddle.net/2r728/
Actualizar
En realidad, como definió las cities
en el controlador principal, su controlador secundario heredará todas las variables de alcance. Entonces, teóricamente, no tienes que llamar a $parent
. El ejemplo anterior también se puede escribir de la siguiente manera:
function ParentCtrl($scope) {
$scope.cities = ["NY","Amsterdam","Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentCities = $scope.cities;
}
Los documentos de AngularJS utilizan este enfoque, here puede leer más sobre $scope
.
Otra actualización
Creo que esta es una mejor respuesta para el cartel original.
HTML
<div ng-app ng-controller="ParentCtrl as pc">
<div ng-controller="ChildCtrl as cc">
<pre>{{cc.parentCities | json}}</pre>
<pre>{{pc.cities | json}}</pre>
</div>
</div>
JS
function ParentCtrl() {
var vm = this;
vm.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl() {
var vm = this;
ParentCtrl.apply(vm, arguments); // Inherit parent control
vm.parentCities = vm.cities;
}
Si usa el controller as
método, también puede acceder al ámbito principal de la siguiente manera
function ChildCtrl($scope) {
var vm = this;
vm.parentCities = $scope.pc.cities; // note pc is a reference to the "ParentCtrl as pc"
}
Como puede ver, hay muchas formas diferentes de acceder a $scopes
.
Violín actualizado
function ParentCtrl() {
var vm = this;
vm.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
var vm = this;
ParentCtrl.apply(vm, arguments);
vm.parentCitiesByScope = $scope.pc.cities;
vm.parentCities = vm.cities;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<div ng-app ng-controller="ParentCtrl as pc">
<div ng-controller="ChildCtrl as cc">
<pre>{{cc.parentCities | json}}</pre>
<pre>{{cc.parentCitiesByScope | json }}</pre>
<pre>{{pc.cities | json}}</pre>
</div>
</div>
También puede sortear la herencia del ámbito y almacenar cosas en el ámbito "global".
Si tiene un controlador principal en su aplicación que envuelve a todos los demás controladores, puede instalar un "gancho" en el ámbito global:
function RootCtrl($scope) {
$scope.root = $scope;
}
Luego, en cualquier controlador secundario, puede acceder al ámbito "global" con $scope.root
. Cualquier cosa que establezca aquí será visible globalmente.
Ejemplo:
function RootCtrl($scope) {
$scope.root = $scope;
}
function ChildCtrl($scope) {
$scope.setValue = function() {
$scope.root.someGlobalVar = ''someVal'';
}
}
function OtherChildCtrl($scope) {
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="RootCtrl">
<p ng-controller="ChildCtrl">
<button ng-click="setValue()">Set someGlobalVar</button>
</p>
<p ng-controller="OtherChildCtrl">
someGlobalVar value: {{someGlobalVar}}
</p>
</div>