AngularJS перевіряє, чи є форма дійсною в контролері


86

Мені потрібно перевірити, чи є форма дійсною в контролері.

Вид:

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

У моєму контролері:

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

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

        ...

Я отримую цю помилку:

TypeError: Cannot read property '$valid' of undefined

Ви обгорнули його навколо функції setBusinessInformation у контролері?
matsko

3
код занадто фрагментований, щоб проаналізувати, що може бути неправильним ... створити просту демонстраційну версію в jsfiddle.net або plunker, яка повторює проблему. Чи є форма в межах сфери BusinessCtrl? не можу сказати, не побачивши більше
charlietfl

@matsko: Ні. Мені потрібно виконати цей код при ініціалізації контролера.
Робер

@charlietfl: Не набагато більше. Я видаляю деякий код, щоб спростити приклад. Так, форма повинна бути в межах BusinessCtrl (контролер встановлений на маршрутах в app.js. Я додаю своє рішення у відповідь нижче. Але, я не знаю, чому це не працює таким чином.
Робер,

Відповіді:


109

Спробуйте це

з огляду:

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

в контролері:

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

або

з огляду:

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

в контролері:

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

Що робити, якщо я хочу перевірити кілька кнопок у формі?
Фахад Мулладжі

це спрацювало для мене, але чому це $scope.formName.$validпризводить до невизначеності?
ps0604

Якщо ви використовуєте ng-if, тоді $ scope.formName. $ Valid не буде працювати, а якщо ви використовуєте ng-show, тоді буде працювати $ scope.formName. $ Valid.
Вайбхав Шаха

2
Це повинна бути найкраща відповідь, проста. Але чи можете ви обробити форму недійсною? Як ви можете показати користувачеві, які введені дані недійсні?
Ніколас Леуччі

1
@ ps0604 formName.$validдоступ можна отримати лише в шаблоні, якщо ви хочете отримати доступ у контролері, вам потрібно створити об'єкт для цього типу $scope.forms.formNameта в шаблоні: <form name="forms.formName"> перевірте цей коментар
Damsorian

29

Я оновив контролер до:

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

Також пам’ятайте, що - якщо форма є модальною, тоді не забудьте оголосити назву форми крапковим позначенням, наприклад: "data.theform" і отримати доступ до неї у своєму контролері як $ scope.data.theform
Джаспер

2
У мене це не працює. Будь ласка, покажіть, як ви отримуєте 'createBusinessForm' у $ -обсязі контролера.
cyrf 02

Речі $ scope пішли, зараз ми використовуємо vmпідхід. Ви можете створити plunker для тієї самої відповіді, використовуючи контролер як підхід до синтаксису. Я не в змозі це зробити. Це буде корисно й іншим, хто шукає відповіді на сьогоднішній контекст. Дякую
ankitd

14

Ось ще одне рішення

Встановіть приховану змінну області в своєму html, тоді ви зможете використовувати її з вашого контролера:

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

Ось повний робочий приклад:

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

BusinessCtrlІніціалізується перед createBusinessForm«з FormController. Навіть якщо у вас є ngControllerформа, вона не працюватиме так, як ви хотіли. Ви не можете допомогти цьому (ви можете створити свій ngControllerDirectiveі спробувати обдурити пріоритет.) Ось як працює angularjs.

Див. Цей plnkr, наприклад: http://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.