web-dev-qa-db-fra.com

Portée du parent d'accès AngularJS à partir du contrôleur enfant

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?

362
zpydee

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.

 

Violon mis à jour

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>

601
Dieterg

Je viens de vérifier

$scope.$parent.someProperty

travaille pour moi.

et ce sera 

{{$parent.someProperty}}

pour la vue.

45
Stepan Suvorov

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;

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.

7
Rubi saini

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) {

    }
2
Gayan Pathirage

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>

1
rustyx

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

0
Benjamin Thvedt

À 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';
0
Donato Szilagyi

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