AngularJS Liaison de données bidirectionnelle dans les directives imbriquées
S'il vous plaît laissez-moi savoir si vous avez besoin de plus d'informations ou souhaitez-moi de clarifier quoi que ce soit. J'ai essayé beaucoup de choses différentes à ce chiffre, mais n'ai pas trouvé de solution.
Je suis relativement nouveau à angularJS et je suis en train de créer une application avec plusieurs couches de données. J'ai quelques base des informations de l'utilisateur stockées dans le champ d'application de l'organisme sur le contrôleur de PageController. J'ai ensuite un formulaire de paramètres qui se charge en utilisant $routeParams (avec le contrôleur SettingsController) qui comprend un couple de des directives sur mesure pour la création de modèles fins. Depuis les directives sont imbriqués, je suis en utilisant la transclusion de charger le second à l'intérieur de la première. Tout cela semble fonctionner très bien.
Mon problème est que je suis en train de référence le champ user.firstname
de l'intérieur le plus intime de la directive et que vous voulez utiliser les deux sens de la liaison de données pour permettre les modifications apportées à la zone de texte à cause de la valeur à la PageController portée d'en changer. Je sais que beaucoup de ces types de problèmes sont causés par l'utilisation de primitives dans ng-model, mais j'ai essayé de tout mettre dans un objet supplémentaire de sorte que je déclencheur prototypes héritage en vain. Ce que je fais mal?
Voici un JSFiddle de mon code, dépouillé autant que possible d'isoler le problème. Dans cet exemple, si je tape à l'extérieur de la zone de texte, qui est directement sur la PageController portée, il va modifier l'intérieure de la zone de texte jusqu'à ce que la zone de texte est modifié, sur lequel la connexion est rompue. Ce qui semble juste comme le problème de l'utilisation de primitives comme décrit dans d'autres questions, mais je ne vois pas où le problème est ici.
HTML:
<body class="event-listing" ng-app="app" ng-controller="PageController">
<div class="listing-event-wrap">
<input type="text" ng-model="user.firstname" />
<div ng-controller="SettingsController">
<section block title="{{data.updateInfo.title}}" description="{{data.updateInfo.description}}">
<div formrow label="{{data.updateInfo.labels.firstname}}" type="textInput" value="user.firstname"></div>
</section>
</div>
</div>
</body>
Angulaire Directives:
app.directive('formrow', function() {
return {
scope: {
label: "@label",
type: "@type",
value: "=value"
},
replace: true,
template: '<div class="form-row">' +
'<div class="form-label" data-ng-show="label">{{label}}</div>' +
'<div class="form-entry" ng-switch on="type">' +
'<input type="text" ng-model="value" data-ng-switch-when="textInput" />' +
'</div>' +
'</div>'
}
});
app.directive('block', function() {
return {
scope: {
title: "@title",
description: "@description"
},
transclude: true,
replace: true,
template: '<div class="page-block">' +
'<h2 data-ng-show="title">{{title}}</h2>' +
'<p class="form-description" data-ng-show="description">{{description}}</p>' +
'<div class="block-inside" data-ng-transclude></div>' +
'</div>'
}
});
Angulaire Contrôleurs:
app.controller("PageController", function($scope) {
$scope.user = {
firstname: "John"
};
});
app.controller("SettingsController", function($scope) {
$scope.data = {
updateInfo: {
title: "Update Your Information",
description: "A description here",
labels: {
firstname: "First Name"
}
}
}
});
source d'informationauteur princjef
Vous devez vous connecter pour publier un commentaire.
Je suis désolé pour le code précédent. Essayez plutôt ceci: http://jsfiddle.net/CxNc2/2/
Au lieu de passer la valeur réelle, je suis en train de passer de l'objet + un pointeur vers la valeur correcte à l'intérieur. J'ai ajouté 'refobject ici:
et j'ai ajouté refobj + valeur ici:
Depuis la zone de texte dans la directive utilise une primitive au lieu d'un objet pour son modèle (
ng-model="value"
plutôt queng-model="someobj.somevalue"
), son modèle est créé uniquement sur l'étendue locale et les parents n'y ont pas accès.La solution est de définir la zone de texte de la directive modèle à l'aide de la point de règle comme une propriété de l'objet:
Puis passer l'ensemble des
user
objet dans la directive, au lieu de simplement les primitives de la propriété:Voici une démo
Le problème est causé par
ng-switch
à Partir de la doc La compréhension de la portée à partir de git.donc, si vous tapez du texte dans la zone de texte.
ci-dessous le code sera exécuté pour la
ng-switch
portée.$scope.value="the text you typed"
De sorte qu'il ne sera pas à consulter la chaîne de prototype de recherche
value
.cela créé une nouvelle propriété pourng-switch
portée.Comment témoigner ?
Si vous modifiez
value
à$parent.value
. tout fonctionnera correctement. parce que dans leng-switch
pour le type primitif (angularjs serait reconnaître levalue
comme type primitif si il n'y a pas de point )$parent
fera référence àformrow
champ d'application de la directive.Essayez de supprimer le
ng-switch
ou faire ce que le doc a dit. le problème va disparaître.Et plus important, le document nous vous recommandons de toujours utiliser un point
.
pour désigner le modèle lorsque vous appliquez un bi-directionnelle de liaison.Si j'ai dit quelque chose de mal . Merci de me corriger et de le rendre droit .merci.