web-dev-qa-db-fra.com

ng-messages angulaires ne montrant que lorsque $ touched est vrai

Je ne fais rien de trop spécial.

J'ai une entrée que je veux valider à chaque coup de clé. Si la validation échoue, affichez l'erreur. N'attendez pas que l'événement de flou déclenche le $ touché.

Je pensais que c'était le cas par défaut, mais apparemment ce n'est pas le cas. J'utilise des matériaux angulaires avec des messages angulaires. Je fais cela pour la détection capslock.

Le balisage:

<form name="primaryLogin" novalidate>
    <md-content layout-padding layout="column">
        <md-input-container flex>
            <label>Login ID</label>
            <input type="text" required="" name="login" ng-model="primary.loginID" capslock>

            <div ng-messages="primaryLogin.$error">
                <div ng-message="required">
                    Please enter a Login ID.
                </div>

                <div ng-message="capslock">
                    Caps Lock is ON!
                </div>
            </div>

            <pre>{{ primaryLogin | json }}</pre>

        </md-input-container>

    </md-content>
</form>

Lorsque je viens pour la première fois sur la page, activez le verrouillage des majuscules et commencez à taper, mon message d'erreur ressemble à ceci:

{
  "$error": {
    "capslock": [
      {
        "$viewValue": "Q",
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": false,
        "$touched": true,
        "$pristine": false,
        "$dirty": true,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "capslock": true
        },
        "$name": "login",
        "$options": {
          "debounce": 100,
          "updateOnDefault": true
        }
      }
    ]
  },
  "$name": "primaryLogin",
  "$dirty": true,
  "$pristine": false,
  "$valid": false,
  "$invalid": true,
  "$submitted": false,
  "login": {
    "$viewValue": "Q",
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": false,
    "$dirty": true,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "capslock": true
    },
    "$name": "login",
    "$options": {
      "debounce": 100,
      "updateOnDefault": true
    }
  }
}

Donc, cela semble fonctionner comme prévu, mais le message d'erreur en réalité ne s'affiche pas jusqu'à ce que l'événement flou se déclenche sur cette entrée particulière. Pour que je puisse entrer avec majuscule, tapez 10 caractères, l'objet d'erreur indique que l'erreur majuscule est présente , mais comme $ touched n’est pas vrai, alors cela ne s’affiche pas.

Une fois que $ touched est défini sur true, je peux alors revenir en arrière et tout fonctionne comme prévu.

Des idées? Merci d'avance!

13
TyMayn

Changement 

<div ng-messages="primaryLogin.$error">

à

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty">

Vous pouvez aussi essayer 

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$touched">

OR

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$pristine">

Vous pouvez également les matraquer comme ainsi pour le contrôle ET conditionnel:

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty && primaryLogin.login.$touched && primaryLogin.login.$pristine"> 

ou pour la vérification conditionnelle OR:

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty || primaryLogin.login.$touched || primaryLogin.login.$pristine">

Essayez ce qui précède un à un pour savoir lequel correspond à votre cas.

20
Devner

Dans la version antérieure à 1.0 de Angular Material (c'est-à-dire <= v0.11.4), c'était le cas: Le message ng était affiché par défaut. 

Cependant, la spécification de conception matérielle indique:

Afficher le texte d'erreur uniquement après une interaction de l'utilisateur avec un champ. Si l'utilisateur saisit des données incorrectes, le texte d'assistance peut se transformer en texte d'erreur.

Si vous souhaitez afficher les messages avant l'interaction de l'utilisateur, vous pouvez ajouter "md-auto-hide = 'false'" à votre directive ng-messages.

<div ng-messages="primaryLogin.$error" md-auto-hide='false'></div>

J'ai trouvé cette solution de: ici

4
sung

Vérifiez avec ng-show="primaryLogin.login.$invalid && primaryLogin.login.$touched". Cela a fait le tour pour moi.

1
Kumar Immanuel

Utilisez md-is-error Exemple:

<md-input-container md-is-error="true">

"Lorsque l'expression donnée a la valeur true, le conteneur en entrée passe en état d'erreur. Erreur par défaut si l'erreur a été sélectionnée et que l'entrée a été touchée."

https://material.angularjs.org/1.1.3/api/directive/mdInputContainer