393 votes

AngularJS Accéder à la portée parente depuis le 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 pour accéder aux propriétés du parent dans le html imbriqué en utilisant $parent.vm.property, mais je n'arrive pas à trouver comment accéder à la propriété du parent depuis mon contrôleur enfant.

J'ai essayé d'injecter $scope et ensuite d'utiliser $scope.$parent.vm.property, mais cela ne fonctionne pas?

Quelqu'un peut-il offrir des conseils?

634voto

Dieter Goetelen Points 2958

Si votre HTML est comme ci-dessous, vous pouvez faire quelque chose comme ceci :

Ensuite, vous pouvez accéder à la portée parente comme suit :

function ParentCtrl($scope) {
    $scope.cities = ["NY", "Amsterdam", "Barcelona"];
}

function ChildCtrl($scope) {
    $scope.parentcities = $scope.$parent.cities;
}

Si vous voulez accéder à un contrôleur parent depuis votre vue, vous devez faire quelque chose comme ceci :

   {{$parent.property}}

Voir jsFiddle : http://jsfiddle.net/2r728/

Mise à 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. Théoriquement, vous n'avez donc pas besoin d'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 lire davantage sur le $scope.

Autre mise à jour

Je pense que c'est une meilleure réponse pour l'auteur initial.

HTML

        {{cc.parentCities | json}}
        {{pc.cities | json}}

JS

function ParentCtrl() {
    var vm = this;
    vm.cities = ["NY", "Amsterdam", "Barcelona"];
}

function ChildCtrl() {
    var vm = this;
    ParentCtrl.apply(vm, arguments); // Hériter du contrôle parent

    vm.parentCities = vm.cities;
}

Si vous utilisez la méthode controller as, vous pouvez également accéder à la portée parente comme suit :

function ChildCtrl($scope) {
    var vm = this;
    vm.parentCities = $scope.pc.cities; // notez que pc est une référence au "ParentCtrl as pc"
}

Comme vous pouvez le constater, il existe de nombreuses façons d'accéder aux $scopes.

Fiddle 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;
}

    {{cc.parentCities | json}}
    {{cc.parentCitiesByScope | json }}
    {{pc.cities | json}}

0 votes

Pouvez-vous faire un lien vers la documentation de cette fonctionnalité?

7 votes

Je pense que les deux problèmes avec votre dernière mise à jour sont 1. L'héritage de la portée parentale peut entraîner des conflits potentiels de namespace et 2. Nécessite la connaissance que l'alias du contrôleur parent est 'pc'. Cela rend la réutilisation plus difficile.

0 votes

Je suis tout à fait d'accord avec vous. Je voulais simplement souligner qu'il existe de nombreuses façons d'accéder à la portée.

49voto

STEVER Points 1545

Je viens de vérifier

$scope.$parent.someProperty

fonctionne pour moi.

et ce sera

{{$parent.someProperty}}

pour la vue.

0 votes

Hmmm, cela ne fonctionne pas pour moi. Je me demande si cela a à voir avec le contrôleur en tant que syntaxe vm.

0 votes

Si vous avez nommé le contrôleur parent, alors vous supprimeriez $parent du modèle et vous auriez {{vm.someProperty}}

9voto

Rubi saini Points 2405

Lorsque vous utilisez la syntaxe as, comme ParentController as parentCtrl, pour définir un contrôleur, alors pour accéder aux variables de la portée parent dans le contrôleur enfant, utilisez ce qui 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.

2voto

Gayan Pathirage Points 16

Parfois, vous pouvez avoir besoin de mettre à jour directement les propriétés parent dans la portée de l'enfant. par exemple, besoin de sauvegarder une date et une heure du contrôle parent après les modifications par un contrôleur enfant. par exemple Code dans JSFiddle

HTML

JS

    function Parent($scope) {
       $scope.event = {
        date: '2014/01/1',
        time: '10:01 AM'
       }
    }

    function Child($scope) {

    }

1voto

rustyx Points 2722

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 englobe tous les autres contrôleurs, vous pouvez installer un "hook" dans la portée globale :

function RootCtrl($scope) {
    $scope.root = $scope;
}

Ensuite, dans n'importe quel contrôleur enfant, vous pouvez accéder à la portée "globale" avec $scope.root. Tout ce que vous définissez ici sera globalement visible.

Exemple:

function RootCtrl($scope) {
  $scope.root = $scope;
}

function ChildCtrl($scope) {
  $scope.setValue = function() {
    $scope.root.someGlobalVar = 'someVal';
  }
}

function OtherChildCtrl($scope) {
}

    Définir someGlobalVar

    Valeur de someGlobalVar : {{someGlobalVar}}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X