web-dev-qa-db-fra.com

Est-il possible de mettre à jour la portée parent à partir de Angular avec la portée: true?

J'ai besoin d'hériter de la portée d'un contrôleur parent dans une directive. Je ne veux pas nécessairement laisser de champ: faux. Je ne veux pas non plus nécessairement utiliser une étendue isolée, car cela nécessite beaucoup de travail pour obtenir les valeurs qui me tiennent à cœur correctement (pensez à beaucoup de valeurs dans un contrôleur parent).

Est-il judicieux d'utiliser scope:true dans ma directive si je veux mettre à jour la portée parent?

<div ng-controller="MyCtrl">
      Hello, {{name}}!
        <my-directive></my-directive>
</div>
var myApp = angular.module('myApp',[]);

//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
    $scope.name = 'Dave';
}


myApp.directive('myDirective', function() {
    return {
        scope: true,
        restrict: 'EA',
        link: function(scope, elem, attrs) {
            scope.updateName = function(newName) {
                console.log('newName is: ' + newName);
                scope.name = newName;
            }
        },
        template: '<input ng-model="updatedName" placeholder="new name value"> <button ng-click="updateName(updatedName)">Update</button>'
    }
})

Veuillez vérifier le violon

33
binarygiant

Bien que @ user1737909 ait déjà référencé la question SO à lire ( Quelles sont les nuances de l'héritage prototypique/prototypique dans AngularJS? , qui expliquera le problème et recommandera diverses manières) pour le réparer), nous essayons normalement de donner la réponse sur SO.

Donc, la raison pour laquelle votre violon ne fonctionne pas est parce que lorsqu'un type primitif (c'est-à-dire une chaîne, un nombre ou un type booléen) est écrit - par exemple, scope.name = newName - "l'écriture" va toujours à la portée/à l'objet local. En d'autres termes, la portée enfant obtient sa propre propriété name qui masque la propriété parent du même nom. Le correctif consiste à utiliser un objet, plutôt qu'un type primitif, dans la portée parent. La portée enfant obtiendra alors une référence à cet objet. Toutes les écritures dans les propriétés de l'objet (qu'elles proviennent du parent ou de l'enfant) iront à cet objet. (La portée enfant n'a pas son propre objet.)

$scope.obj = {name: 'Dave'};

Puis dans votre directive:

scope.obj.name = newName;

et HTML:

Hello, {{obj.name}}!

fiddle

50
Mark Rajcok

L'héritage de portée ne signifie pas que la définition de la valeur d'un enfant définit la valeur de son parent.

Au lieu de faire scope.name = newName sur la portée enfant, ajoutez une méthode à la portée parent, qui fera le même travail mais sur la portée parent, et appelez-la depuis la portée enfant puisque l'enfant hérite de cette méthode.

15
lib3d

Dans votre fonction de lien, vous écririez dans la portée parent (la portée globale "$ scope") comme ceci: scope. $ Parent.name = newName;

6
Rebekah Waterbury