AngularJS-accès à l'enfant champ d'application

si j'ai les contrôleurs suivants:

function parent($scope, service) {
    $scope.a = 'foo';

    $scope.save = function() {
        service.save({
            a:  $scope.a,
            b:  $scope.b
        });
    }
}

function child($scope) {
    $scope.b = 'bar';
}

Quelle est la bonne façon de laisser parent lire b sur child ? S'il est nécessaire de définir b dans parent , cela ne le rendrait-il pas sémantiquement incorrect en supposant que b est une propriété qui décrit quelque chose liée à child et non parent ?

mise à Jour: Penser plus à ce sujet, si plus d'un enfant avait b cela créerait un conflit pour parent sur lequel b pour récupérer. Ma question reste, Quelle est la bonne façon d'accéder à b de parent ?

105
demandé sur Aziz Alfoudari 2012-11-17 09:38:46

6 réponses

Scopes en AngularJS utiliser l'héritage prototypique, lors de la recherche d'une propriété dans un enfant scope l'interprète regardera en haut de la chaîne prototype à partir de l'enfant et continuer aux parents jusqu'à ce qu'il trouve la propriété, pas l'inverse.

vérifier les commentaires de Vojta sur la question https://groups.google.com/d/msg/angular/LDNz_TQQiNE/ygYrSvdI0A0J

en un mot: vous ne pouvez pas accéder à des portées enfant à partir d'un scope parent.

vos solutions:

  1. définir les propriétés des parents et y accéder auprès des enfants (lire le lien ci-dessus)
  2. utiliser un service pour partager l'état
  3. transmettre les données à travers les événements. $emit envoie les événements vers le haut aux parents jusqu'à ce que la portée de base et $broadcast envoie les événements vers le bas. Cela pourrait vous aider à garder les choses sémantiquement correctes.
156
répondu jaime 2012-11-17 06:11:37

bien que la réponse de jm-soit la meilleure façon de traiter ce cas, pour référence future, il est possible d'accéder à child scopes en utilisant $$$childHead, $childTail, $nextSibling et $$$prevSibling members. Ceux-ci ne sont pas documentés de sorte qu'ils peuvent changer sans préavis, mais ils sont là si vous vraiment besoin de parcourir des portées.

// get $$childHead first and then iterate that scope's $$nextSiblings
for(var cs = scope.$$childHead; cs; cs = cs.$$nextSibling) {
    // cs is child scope
}

Violon

79
répondu Jussi Kosunen 2013-05-31 09:00:48

Vous pouvez essayer ceci:

$scope.child = {} //declare it in parent controller (scope)

ajouter ensuite dans le régulateur pour enfants (scope):

var parentScope = $scope.$parent;
parentScope.child = $scope;

Maintenant, le parent a accès à l'enfant.

47
répondu Farzin Mo 2015-02-06 21:05:21

une solution possible est d'injecter le contrôleur enfant dans le contrôleur parent en utilisant une fonction init.

mise en œuvre Possible:

<div ng-controller="ParentController as parentCtrl">
   ...

    <div ng-controller="ChildController as childCtrl" 
         ng-init="ChildCtrl.init()">
       ...
    </div>
</div>

où dans ChildController vous avez :

app.controller('ChildController',
    ['$scope', '$rootScope', function ($scope, $rootScope) {
    this.init = function() {
         $scope.parentCtrl.childCtrl = $scope.childCtrl;
         $scope.childCtrl.test = 'aaaa';
    };

}])

Donc maintenant dans le ParentController vous pouvez utiliser :

app.controller('ParentController',
    ['$scope', '$rootScope', 'service', function ($scope, $rootScope, service) {

    this.save = function() {
        service.save({
            a:  $scope.parentCtrl.ChildCtrl.test
        });
     };

}])

Important:

Pour fonctionner correctement, vous devez utilisez la directive ng-controller et renommez chaque contrôleur en utilisant as comme je l'ai fait dans l'eg html.

Conseils:

Utilisez le plugin chrome ng-inspector pendant le processus. Il va vous aider à comprendre l'arbre.

4
répondu borracciaBlu 2015-07-03 03:26:04

Oui, nous pouvons assigner des variables de child controller aux variables de parent controller. C'est une façon possible:

Overview: le but principal du code, ci-dessous, est d'attribuer $scope du contrôleur enfant.variable à $ scope du contrôleur parent.assigner

explication: il y a deux contrôleurs. Dans le html, notez que le contrôleur parent entoure le contrôleur enfant. Cela signifie que le le contrôleur parent sera exécuté avant le contrôleur enfant. Ainsi, setValue() sera d'abord défini et ensuite le contrôle ira au contrôleur enfant. $portée.variable sera assignée comme "enfant". Alors ce champ enfant sera passé comme argument à la fonction de contrôleur parent, où $scope.attribuer obtenez la valeur comme "enfant",

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script type="text/javascript">
    var app = angular.module('myApp',[]);

    app.controller('child',function($scope){
        $scope.variable = "child";
        $scope.$parent.setValue($scope);
    });

    app.controller('parent',function($scope){
        $scope.setValue = function(childscope) {
            $scope.assign = childscope.variable;
        }
    });

</script>
<body ng-app="myApp">
 <div ng-controller="parent">
    <p>this is parent: {{assign}}</p>
    <div ng-controller="child">
        <p>this is {{variable}}</p>
    </div>
 </div>
</body>
</html>
1
répondu rupali317 2017-09-07 14:23:08

je ne suis pas sûr de savoir si ou de ne pas vous "doit" l'accès de l'enfant au parent, mais c'est possible. Je le sais parce que je l'ai fait moi-même. Voici mon scénario:

j'ai une fonction qui navigue dans mes pages en modifiant la chaîne à l'intérieur d'une variable. Que cette variable est référencée dans l'index principal.fichier html en ng-include. Ainsi, lorsque la chaîne de caractères est changée, un nouveau fichier html est chargé dans ce ng-include. À l'intérieur d'un de ces fichiers html j'ai un autre ng-include. Pensez à ce que d'une petite fenêtre dans la première fenêtre. Chaque fois que je change le contenu de ces fenêtres, je change aussi le contenu d'un panneau latéral. Ce panneau latéral est au niveau parent. Mais, quand je vais dans la fenêtre plus petite dans le parent, ce panneau latéral de niveau parent a des liens de navigation qui changent les choses dans la petite fenêtre. Puisque le panneau latéral est au niveau parent et la navigation pour la fenêtre plus petite est prise en charge dans son propre contrôleur à l'enfant, lorsque je clique sur les liens sur le côté du panneau de il a à modifier le contrôleur enfant. Cela peut être une mauvaise programmation. Honnêtement, je ne sais pas. J'ai commencé avec angularjs il y a quelques mois et j'apprends encore. Mais, pour le faire fonctionner pour mon scénario, j'ai fait une fonction dans le champ parent, qui s'appelle lorsque le champ child se charge:

function parent($scope, service) {
    setCurrentChildController = function (childScope) {
    this.$scope.childScope = childScope;
}
}

function child($scope) {
    scope.$parent.setCurrentChildController($scope);
}

donc, maintenant la variable $scope de la société mère.childScope est essentiellement le contrôleur de l'enfant portée. Il a accès à toutes les variables et fonctions au sein de l'enfant. Si c'est la mauvaise programmation et n'importe qui peut venir avec une solution alternative au problème avec mon scénario, ce serait super. Mais, ce n'travail si nécessaire.

0
répondu tkd_aj 2014-10-01 16:58:12