0

Je travaille sur plusieurs composants (directives) pour faciliter la validation des formulaires. J'aimerais que les composants soient conscients de l'état de l'élément d'entrée associé (tel que requis). Par exemple ...Accédez directement à l'élément de formulaire à partir de form.FormController?

Markup:

<form name="editUser"> 
    <control-label input="editUser.name">Name</control-label> 
    <input type="text" name="name" ng-model="user.name" required/> 
</form> 

directive:

app.directive("controlLabel", function() { 
    return { 
    restrict: "E", 
    replace: true, 
    transclude: true, 
    scope: { 
     input: "=input" 
    }, 
    template: 
     '<label class="control-label">'+ 
     '<span ng-transclude>{{label}}</span>'+ 
     '<span ng-if="input.required"> (required!)</span>'+ // doesn't work? 
     '</label>' 
    }; 
}); 

Sortie:

<form name="editUser"> 
    <label> 
     <span>Name</span> 
     <span>(required!)</span> 
    </label> 
    <input type="text" name="name" ng-model="user.name" required/> 
</form> 

La source pour form.FormController laisse moi croire que ce n'est pas possible. Y a-t-il un moyen d'avoir au moins accès aux attrs sur l'élément? J'ai pensé utiliser un décorateur, mais jusqu'ici je n'ai pas été capable de comprendre comment cela serait fait.

Répondre

1

Vous devez utiliser input.$validators.required au lieu de input.required comme:

myApp.directive("controlLabel", function() { 
    return { 
    restrict: "E", 
    replace: true, 
    transclude: true, 
    scope: { 
     input: "=input" 
    }, 
    template: 
     '<label class="control-label">'+ 
     '<span ng-transclude>{{label}}</span>'+ 
     '<span ng-if="input.$validators.required"> (required!)</span>'+ 
     '</label>' 
    }; 
}); 

Working Demo

+0

J'ai besoin de l'indicateur d'édition pour toujours afficher, pas seulement sur $ error – Brian

+0

@Brian: Utilisez 'input. $ Validators.required' alors. Mis à jour la réponse ci-dessus. – codef0rmer

+1

merci @ codeF0rmer, c'est exactement ce que je cherchais. Je ne savais même pas $ validateurs existaient: P – Brian

1

Tout d'abord, il y a une erreur dans votre code. Si vous utilisez transclude, vous devrez le déclarer dans votre directive, sinon vous obtiendrez une erreur. En ce qui concerne votre problème, dans le cadre d'une directive, vous pouvez accéder à l'élément DOM. Et pour ce cas particulier d'utilisation, vous pouvez même obtenir par sans créer de champ isolé ou un attribut supplémentaire à tous:

app.directive("controlLabel", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: true,  // if needed, can also use empty isolated scope { } 
     transclude: true, // must declare this 
     template: 
       '<label class="control-label">' + 
       '<span ng-transclude>{{label}}</span>' + 
       '<span ng-if="show"> (required!)</span>' + 
       '</label>', 
     link: function(scope, jqElem, attrs) { 
      // check if next sibling of this directive is required 
      scope.show = (jqElem.next().attr("required") === 'required'); 
     } 
    }; 
}); 

Maintenant votre étiquette de contrôle est vraiment minime et DRY, et la logique est bien encapsulées dans une directive. La seule exigence est que votre directive cible doit être le prochain frère de l'étiquette:

<control-label>Name</control-label> 
<input type="text" name="name" ng-model="user.name" required/> 

Bien sûr, en cas de besoin, vous pouvez utiliser votre jquery -FU pour changer la fonction link en fonction de vos autres exigences.

+0

Merci @ b0nyb0y. Je suppose que je pourrais également utiliser le #id du pour capturer c'est lié

+0

@Brian Ah, vous avez raison sur le problème de portée, mon mauvais. Sans déclarer 'scope', chaque entrée partagera la même valeur' show' sous l'ensemble du contrôleur. Donc je suppose que dans ce cas, vous pouvez soit ** a) ** déclarer 'scope: true' (créer une portée enfant), soit ** b) **' scope: {} '(créer une portée isolée). Votre choix dépend de si vous souhaitez hériter des variables parent dans la portée de la directive ou non. Je vais corriger la réponse maintenant. – b0nyb0y

Questions connexes