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中的路由上设置的。我在下面的答案中添加了我的解决方案。但是,我不知道为什么不能这样工作。)
Rober

Answers:


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
  }
};

如果我要验证表单中的多个按钮怎么办?
Fahad Mullaji'3

这对我有用,但是为什么$scope.formName.$valid导致未定义?
ps0604 '16

如果使用ng-if,则$ scope.formName。$ valid将不起作用;如果使用ng-show,则$ scope.formName。$ valid将起作用。
Vaibhav Shaha

2
这应该是最好的答案,很简单。但是您可以处理无效的表格吗?您如何向用户显示哪些输入无效?
Nicolas Leucci

1
@ ps0604formName.$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进行访问
Jasper

2
这对我不起作用。请说明如何将“ createBusinessForm”放入控制器的$ scope中。
cyrf '16

$ scope的事情已经过去,现在我们正在使用vm方法。您可以通过使用控制器作为语法方法来为相同的答案创建一个插件。我做不到。这对于在今天的背景下寻求答案的其他人也将有所帮助。谢谢
2013年

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在之前被初始化createBusinessFormFormController。即使您ngController在表单上使用,也无法按照您想要的方式工作。您ngControllerDirective无能为力(您可以创建自己的,并尝试欺骗优先级。)这就是angularjs的工作方式。

例如,请参见以下plnkr:http ://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.