J'ai configuré mes contrôleurs en utilisant data-ng-controller="xyzController as vm"
J'ai un scénario avec des contrôleurs imbriqués parent/enfant. Je n'ai aucun problème à accéder aux propriétés parent dans le code HTML imbriqué en utilisant $parent.vm.property
, mais je ne peux pas comprendre comment accéder à la propriété parent à partir de mon contrôleur enfant.
J'ai essayé d'injecter $ scope puis d'utiliser $scope.$parent.vm.property
, mais cela ne fonctionne pas?
Quelqu'un peut-il offrir des conseils?
Si votre HTML est comme ci-dessous, vous pouvez faire quelque chose comme ceci:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
Ensuite, vous pouvez accéder à la portée parent comme suit
function ParentCtrl($scope) {
$scope.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentcities = $scope.$parent.cities;
}
Si vous souhaitez accéder à un contrôleur parent depuis votre vue, vous devez procéder de la manière suivante:
<div ng-controller="xyzController as vm">
{{$parent.property}}
</div>
Voir jsFiddle: http://jsfiddle.net/2r728/
Mettre à jour
En fait, puisque vous avez défini cities
dans le contrôleur parent, votre contrôleur enfant héritera de toutes les variables de portée. Donc théoriquement, vous n'avez pas à appeler $parent
. L'exemple ci-dessus peut également être écrit comme suit:
function ParentCtrl($scope) {
$scope.cities = ["NY","Amsterdam","Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentCities = $scope.cities;
}
Les documents AngularJS utilisent cette approche, ici vous pouvez en savoir plus sur le $scope
.
Une autre mise à jour
Je pense que c'est une meilleure réponse à l'affiche originale.
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 vous utilisez la méthode controller as
, vous pouvez également accéder à la portée parent comme suit
function ChildCtrl($scope) {
var vm = this;
vm.parentCities = $scope.pc.cities; // note pc is a reference to the "ParentCtrl as pc"
}
Comme vous pouvez le constater, il existe différentes manières d’accéder à $scopes
.
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>
Je viens de vérifier
$scope.$parent.someProperty
travaille pour moi.
et ce sera
{{$parent.someProperty}}
pour la vue.
Lorsque vous utilisez la syntaxe as
, telle que ParentController as parentCtrl
, pour définir un contrôleur, puis pour accéder à la variable de portée parent dans controller controller use comme suit:
var id = $scope.parentCtrl.id;
Où parentCtrl
est le nom du contrôleur parent utilisant la syntaxe as
et id
est une variable définie dans le même contrôleur.
Parfois, vous devrez peut-être mettre à jour les propriétés parent directement dans la portée de l'enfant. par exemple. Il faut enregistrer la date et l'heure du contrôle parent après les modifications apportées par un contrôleur enfant. par exemple Code dans 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) {
}
Vous pouvez également contourner l'héritage de la portée et stocker des éléments dans la portée "globale".
Si vous avez un contrôleur principal dans votre application qui enveloppe tous les autres contrôleurs, vous pouvez installer un "raccordement" à la portée globale:
function RootCtrl($scope) {
$scope.root = $scope;
}
Ensuite, dans tout contrôleur enfant, vous pouvez accéder à la portée "globale" avec $scope.root
. Tout ce que vous définissez ici sera visible dans le monde entier.
Exemple:
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>
Je crois que j'ai eu un dilemme similaire récemment
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
}
Ma configuration était un peu différente, mais la même chose devrait probablement toujours fonctionner
À partir d'un composant enfant, vous pouvez accéder aux propriétés et aux méthodes du composant parent avec 'require'. Voici un exemple:
Parent:
.component('myParent', mymodule.MyParentComponent)
...
controllerAs: 'vm',
...
var vm = this;
vm.parentProperty = 'hello from parent';
Enfant:
require: {
myParentCtrl: '^myParent'
},
controllerAs: 'vm',
...
var vm = this;
vm.myParentCtrl.parentProperty = 'hello from child';
Super facile et fonctionne, mais je ne sais pas pourquoi ....
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
}
};
});