2013-10-16 20 views
21

Spero che questo non sia un duplicato - molte domande simili ma non riesco a trovare una risposta che funzioni.Angularjs ottiene la validità del campo modulo all'interno della direttiva

Ho una direttiva angolare, in tal modo:

app.directive('emailInput', function(){ 
    return { 
     restrict: 'E', 
     templateUrl: 'template.html', 
     link: function(scope, elem, attrs, ctrl){ 
      elem.bind('keyup', function(){ 
       // TODO - what? 
      }) 
     } 
    } 
} 

e il template HTML:

<input type="email" required ng-model="emailAddress" /> 

Senza conoscere il nome del modulo, all'interno della funzione link, voglio conoscere il valore della proprietà emailAddress.$valid - come posso ottenere questo?

+0

Vedere anche qui (http://stackoverflow.com/a/41072188/1021943) per una soluzione più recente (e probabilmente più pulita) con AngularJS> = 1.5.0. –

risposta

32

È possibile richiedere la formController che darebbe di accedere a tutti gli ingressi registrati alla forma

app.directive('emailInput', function(){ 
    return { 
     require: '^form', // We look for it on a parent, since it will be defined somewhere higher on the DOM. 
     restrict: 'E', 
     templateUrl: 'template.html', 
     link: function(scope, elem, attrs, ctrl){ 
      elem.bind('keyup', function(){ 
       ctrl.emailAddress.$valid //check validity 
      }) 
     } 
    } 
} 

Ricordate che angolare registra elementi di input per nome. Quindi devi dare il vostro input un nome attributo

<input type="email" required ng-model="emailAddress" name="emailAddress" /> 

Io consiglio anche, eventualmente, solo di passaggio tutto ciò attraverso un attributo direttiva. Probabilmente non vuoi codificare i nomi dei campi. Quindi potresti semplicemente avere un attributo che prende la validità

inputIsValid='formName.emailAddress.$valid' 

E valutare (o $ guardarlo) nella direttiva.

+0

Perfetto, grazie sempre così tanto. –

+0

Possiamo ottenere l'accesso al campo con un nome come questo: name = 'some.thing'? – Rroman

+0

Non ho provato da solo, ma js ti permette di usare qualsiasi stringa come chiave su un oggetto. L'unica differenza è che dovrai utilizzare operatori di parentesi quadre per accedervi. ctrl ['some.thing']. $ Valido – Adam

2

È possibile verificare la validità più facilmente senza conoscere il nome degli elementi di input.

app.directive('emailInput', function(){ 
    return { 
     require: '^form', // We look for it on a parent, since it will be defined somewhere higher on the DOM. 
     restrict: 'E', 
     templateUrl: 'template.html', 
     link: function(scope, elem, attrs, ctrl){ 
      elem.bind('keyup', function(){ 
       ctrl.$valid //check validity here 
      }) 
     } 
    } 
} 
1

Questo è un vecchio post, ma per la gente che arriva qui da googling, questo è il modo più pulito per controllare la validità di un ingresso nella vostra direttiva senza conoscere il suo nome, in modo da poter utilizzare la direttiva su ogni ingresso elemento.

Hai solo bisogno di richiedere il controller ngModel:

app.directive('emailInput', function(){ 
    return { 
    require: 'ngModel' 
    restrict: 'E', 
    templateUrl: 'template.html', 
    link: function(scope, elem, attrs, ngModelCtrl){ 
     elem.bind('keyup', function(){ 
      ngModelCtrl.$valid //check validity 
     }) 
    } 
    } 
} 

Vedi il documento AngularJS per ngModel.NgModelController, $valid nella sezione Proprietà:

https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

+0

La tua risposta mostra un codice che è * quasi * una copia/incolla di @preservant sopra di te. O spiega perché la tua è migliore o modifica la risposta di @ preservant. Si scrive 'require: 'ngModel'' invece di' require:'^form''. Il resto è fondamentalmente lo stesso. –

+0

@OferZelig La differenza è con 'require: '^ form'' deve andare a cercare' form' sui genitori dell'elemento ma con 'require:' ngModel'' guarda solo sull'elemento stesso. Inoltre, 'ngModel' è davvero la cosa di cui abbiamo bisogno, non il' form' – Masoud

+0

Sì, quindi penso che sia meglio modificare la risposta precedente e avere uno canonico, è meno confuso per le persone. –

1

so che è un vecchio thread, ma se qualcuno incontra questo problema, ho risolto il problema:

app.directive('emailInput', function(){ 
    return { 
     restrict: 'E', 
     templateUrl: 'template.html', 
     controller:function($scope){ 
     $scope.isInvalid = function(){ 
      return $scope.myelem.data().$ngModelController.$invalid; 
     } 
     }, 
     link: function(scope, elem, attrs){ 
      $scope.myelem = $(elem).find("input"); 
     } 
    } 
} 
0

Ecco una direttiva che fisserà sporco per vero anche se nulla è stato digitato.

Per impostazione predefinita $ sporco è impostato se qualcosa sia stato digitato e non avrebbe mostrato un messaggio di errore richiesto fino a quando l'utente invia . Con questo

function() { 
    return function (scope, element, attrs) { 
     $(element).blur(function() { 
      scope.$apply(function() { 
       var field = scope.$eval(attrs.makeDirty); 
       field.$dirty = true; 
      }); 
     }); 
    }; 

HTML:

<label class="fieldLabel" for="confirmEmail">Confirm Email*</label> 
<input type="text" id="confirmEmail" name="confirmEmail" ng-model="confirmEmail" ng-pattern="{{Ctrl.Model.Email.EmailAddress}}" required make-dirty="form.confirmEmail"> 
<span class="error" ng-show="form.confirmEmail.$error.pattern && form.confirmEmail.$dirty">Emails must match</span> 
<span class="error" ng-show="form.confirmEmail.$error.required && (form.$submitted || form.confirmEmail.$dirty)">Confirm your email</span> 

che mi permette di dare un feedback come l'utente sta compilando o tabulazione sul modulo.

0

Lasciate che vi dia un altro modo per farlo, può essere utile in alcuni casi

link: function (scope, element, attrs, formCtrl) { 
    scope.fileSizeError=false; 
    scope.$watch(function() { 
       return formCtrl.fileP.$error.maxSize; 
      },function(newValue) { 
       scope.fileSizeError=newValue; 
      });   
} 

Nel mio caso ero dentro una direttiva che viene utilizzato per caricare un file quindi avevo bisogno di conoscere lo stato del var $ error.maxSize nel template così l'ho fatto in quel modo.

Problemi correlati