AngularJS controlla se il modulo è valido nel controller


86

Devo controllare se un modulo è valido in un controller.

Visualizza:

<form novalidate=""
      name="createBusinessForm"
      ng-submit="setBusinessInformation()"
      class="css-form">
 <!-- fields -->
</form>

Nel mio controller:

.controller(
    'BusinessCtrl',
    function ($scope, $http, $location, Business, BusinessService, 
              UserService, Photo)
    {

        if ($scope.createBusinessForm.$valid) {
            $scope.informationStatus = true;
        }

        ...

Ricevo questo errore:

TypeError: Cannot read property '$valid' of undefined

Lo hai avvolto attorno alla funzione setBusinessInformation all'interno del controller?
matsko

3
codice troppo frammentato per analizzare cosa potrebbe essere sbagliato ... creare una semplice demo in jsfiddle.net o plunker che replica il problema. La forma rientra nell'ambito di applicazione BusinessCtrl? non posso dirlo senza vedere di più
charlietfl

@matsko: No. Devo eseguire questo codice durante l'inizializzazione del controller.
Rober

@charlietfl: non c'è molto di più. Rimuovo del codice per semplificare l'esempio. Sì, il modulo dovrebbe rientrare nell'ambito di BusinessCtrl (il controller è impostato sulle rotte in app.js. Aggiungo la mia soluzione in una risposta di seguito. Ma non so perché non funziona in questo modo.
Rober

Risposte:


109

Prova questo

in vista:

<form name="formName" ng-submit="submitForm(formName)">
 <!-- fields -->
</form>

nel controller:

$scope.submitForm = function(form){
  if(form.$valid) {
   // Code here if valid
  }
};

o

in vista:

<form name="formName" ng-submit="submitForm(formName.$valid)">
  <!-- fields -->
</form>

nel controller:

$scope.submitForm = function(formValid){
  if(formValid) {
    // Code here if valid
  }
};

E se volessi convalidare più pulsanti in un modulo?
Fahad Mullaji

questo ha funzionato per me, ma perché $scope.formName.$validrisulta indefinito?
ps0604

Se usi ng-if allora $ scope.formName. $ Valid non funzionerà e se usi ng-show allora $ scope.formName. $ Valid funzionerà.
Vaibhav Shaha

2
Questa dovrebbe essere la risposta migliore, semplice. Ma potresti gestire il modulo non valido? Come potresti mostrare all'utente quali input non sono validi?
Nicolas Leucci

1
@ ps0604 è formName.$validpossibile accedervi solo nel template, se vuoi accedere nel controller devi creare un oggetto per quel like $scope.forms.formNamee nel template: <form name="forms.formName"> controlla questo commento
Damsorian

29

Ho aggiornato il controller per:

.controller('BusinessCtrl',
    function ($scope, $http, $location, Business, BusinessService, UserService, Photo) {
        $scope.$watch('createBusinessForm.$valid', function(newVal) {
            //$scope.valid = newVal;
            $scope.informationStatus = true;
        });
        ...

Ricorda anche che - Se il modulo è un modale, ricorda di dichiarare il nome del modulo come notazione a punti, ad esempio: "data.theform" e accedervi nel controller come $ scope.data.theform
Jasper

2
Questo non funziona per me. Mostra come ottenere 'createBusinessForm' nel $ scope del controller.
cyrf

$ scope le cose sono andate, ora stiamo usando l' vmapproccio. puoi creare un plunker per la stessa risposta utilizzando il controller come approccio sintattico. Non sono in grado di farlo. Sarà utile anche per altri che cercano una risposta con il contesto di oggi. Grazie
ankitd

14

Ecco un'altra soluzione

Imposta una variabile di ambito nascosta nel tuo html, quindi puoi usarla dal tuo controller:

<span style="display:none" >{{ formValid = myForm.$valid}}</span>

Ecco l'esempio di lavoro completo:

angular.module('App', [])
.controller('myController', function($scope) {
  $scope.userType = 'guest';
  $scope.formValid = false;
  console.info('Ctrl init, no form.');
  
  $scope.$watch('myForm', function() {
    console.info('myForm watch');
    console.log($scope.formValid);
  });
  
  $scope.isFormValid = function() {
    //test the new scope variable
    console.log('form valid?: ', $scope.formValid);
  };
});
<!doctype html>
<html ng-app="App">
<head>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
</head>
<body>

<form name="myForm" ng-controller="myController">
  userType: <input name="input" ng-model="userType" required>
  <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
  <tt>userType = {{userType}}</tt><br>
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
  <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
  
  
  /*-- Hidden Variable formValid to use in your controller --*/
  <span style="display:none" >{{ formValid = myForm.$valid}}</span>
  
  
  <br/>
  <button ng-click="isFormValid()">Check Valid</button>
 </form>
</body>
</html>


4

Il BusinessCtrlviene inizializzata prima che le createBusinessForm's FormController. Anche se hai ngControlleril modulo sul modulo non funzionerà come volevi. Non puoi ngControllerDirectivefarci niente (puoi creare il tuo e cercare di ingannare la priorità.) È così che funziona angularjs.

Vedi questo plnkr ad esempio: http://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.