Comme le titre l'indique, ngMessagesInclude est traité après la suppression de ngMessages parent du DOM. Il échoue car angular ne peut pas trouver le contrôleur parent pour lier les messages internes. Cela ne se produit pas lorsque les ngMessage
sont insérés dans l'élément ngMessages
ou lorsque l'élément parent est toujours présent sur DOM.
Avoir un ng-message comme celui-ci :
<div ng-if="myForm.$submitted" ng-messages="myForm.myName.$error">
<div ng-messages-include="messages.html"></div>
</div>
La soumission est déclenchée par :
this.change = function(myForm) {
var self = this;
myForm.$setSubmitted(); // event A
$scope.$applyAsync(function () {
self.currentStep = 'step2.html'; // event B
});
};
À l'événement (A), messages.html
est téléchargé. Comme il utilise $templateRequest
, la liaison est bloquée jusqu'au retour du serveur. Pendant ce temps, l'événement (B) procède à la suppression de ngMessages
et de ses enfants de DOM. Plus tard, le contenu ngMessagesInclude arrivera et angular le compilera. Mais à ce stade, il n'y a plus aucun moyen de récupérer le contrôleur ngMessages
.
Plnkr : http://plnkr.co/edit/0GOOLERvfj7n9vDVEyZp?p=preview
La plupart du temps, cela se produira avec une condition ngIf
.
Testé par rapport à la version 1.4.4.
J'ai trouvé un moyen d'éviter ça :
ng-if="myForm.$submitted && myForm.myName.$invalid"
Pour résoudre ce problème côté composant, le require: '^^ngMessages'
pourrait être rendu facultatif et vérifier cette condition lors de la liaison.
Une solution simple serait de vérifier si la portée a été détruite avant de compiler/lier le HTML dans ngMessagesInclude :
$templateRequest(src).then(function(html) {
if (scope.$$destroyed) return;
// ...
}
C'est ainsi que ngInclude gère le même scénario.
La gestion de cela est similaire à celle de ngInclude
semble raisonnable.
@awerlang ou @jpekkala , seriez-vous intéressé à soumettre un PR ?
Sûr. Je soumettrai un PR dans quelques jours.