AngularJS: Portée parent non mise à jour dans la directive (avec portée isolée) Liaison bidirectionnelle
J'ai le code suivant, qui peut également être tripoté sur http://jsfiddle.net/garukun/u69PT/.
Vue:
<div data-ng-app="testApp">
<div data-ng-controller="testCtrl">
<strong>{{pkey}}</strong>
<span data-test-directive data-parent-item="pkey"
data-parent-update="update(pkey)"></span>
</div>
</div>
JS:
var testApp = angular.module('testApp', []);
testApp.directive('testDirective', function ($timeout) {
return {
scope: {
key: '=parentItem',
parentUpdate: '&'
},
replace: true,
template: '<div><p>{{key}}</p>' +
'<button data-ng-click="lock()">Lock</button>' +
'</div>',
controller: function ($scope, $element, $attrs) {
$scope.lock = function () {
$scope.key = 'D+' + $scope.key;
console.log('DIR :', $scope.key);
//Expecting $scope.$parent.pkey to have also been
//updated before invoking the next line.
$scope.parentUpdate();
//$timeout($scope.parentUpdate); //would work.
};
}
};
});
testApp.controller('testCtrl', function ($scope) {
$scope.pkey = 'golden';
$scope.update = function (k) {
//Expecting local variable k, or $scope.pkey to have been
//updated by calls in the directive's scope.
console.log('CTRL:', $scope.pkey, k);
$scope.pkey = 'C+' + k;
console.log('CTRL:', $scope.pkey);
};
});
En gros, je suis la mise en place de la directive isolé application, dans lequel je suis les deux sens de la liaison d'une propriété (clé) de la portée parent (pkey), et également de déléguer une méthode (parentUpdate) à être appelée dans le contexte de la portée parent.
Maintenant, au cours d'une ng-cliquez sur gestionnaire d'événement dans la directive, je voudrais invoquer la parentUpdate méthode et de faire quelque chose à l'intérieur. Quand je suis en invoquant la méthode, je m'attends à ce que mes parent champ d'application du modèle ont été mis à jour. Mais en réalité, il n'est pas, et c'est ce qui est déroutant pour moi.
C'est probablement à cause de manque des $digest cycles dans le milieu, depuis l'emballage de la parentUpdate appel à $timeout ne fonctionnent pas comme prévu.
Quelqu'un pourrait jeter quelque lumière sur ce qu'il manque? Ou comment correctement invoqué parentUpdate?
source d'informationauteur Steve
Vous devez vous connecter pour publier un commentaire.
OK, je vais prendre une fissure à celui-ci... Il semble que vous êtes en modifiant à la fois l'enfant isolé ET variables parents avant un
$digest
cycle où la bi-direction de la logique synchronise les deux. En voici les détails:lock()
fonction est exécutée en cliquant sur le bouton. Cela met à jour les isolés$scope.key
variable. REMARQUE: Ce n'est PAS immédiatement mise à jour le parent$scope.pKey
; qui devrait normalement se produire lors de la prochaine$digest
cycle, mais n'est pas dans ce cas. Lire la suite...lock()
vous appelezparentUpdate()
qui met à jour les parents$scope.pKey
variable.$digest
cycle exécute. Quand elle boucle le parent d'un changement de$scope.pKey
est correctement détecté.$scope.pKey
déclenche unewatch()
qui a été créé par le bi-directionnelle de liaison dans la partie isolée de la portée. Ces lignes sont les "critiques"..watch()
créé par l'isolé champ d'application vérifie si c'est la valeur de la bi-directionnelle de liaison est en phase avec le parent de la valeur. Si elle ne l'est pas (et ce n'est pas dans ce scénario) de la société mère valeur est copiée à l'isolé portée même si le caractère isolé de la portée de la valeur a changé aussi et, en fait, a changé la première.Misko fameux post sur Angulaire de la liaison de données décrit les avantages de la
$digest
approche axée sur le cycle. Ce que vous voyez ici est un être conscient des effets secondaires de la$digest
s'approche du changement coalesence où, comme le code source commentaire dit,parent changé et il a préséance
... et cela signifie que votre isolé portée du changement perd.La
$timeout()
approche que vous avez noté ci-dessus permet d'éviter ce problème en changeant seulement la partie isolée de la portée de la valeur dans la première$digest
cycle qui lui permet d'être copié à la portée parent avec succès, PUIS en appelantparentUpdate()
La
$compiler
de la documentation dit:Cela signifie que, à l'étape #2 vous pouvez passer à votre valeur de
pkey
via un objet de la carte comme ceci:Voici la mise à jour du violon: http://jsfiddle.net/KbYcr/
À l'aide de
$scope.$apply()
au lieu de$scope.$digest()
travaille trop. Ce sera également déclencher la réflexion sur la rootScope.