AngularJS在控制器中检查表单是否有效

88
我需要在控制器中检查一个表单是否有效。
视图:
<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:不行。我需要在控制器初始化时执行这段代码。 - Rober
@charlietfl: 没有太多的内容了。我删除了一些代码来简化示例。是的,表格应该在BusinessCtrl的作用域内(控制器在app.js的路由中设置)。我在下面的答案中添加了我的解决方案。但是,我不知道为什么这样不起作用。 - Rober
5个回答

111

试试这个

在视图中:

<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
这对我有用,但为什么 $scope.formName.$valid 的结果是未定义的? - ps0604
如果您使用ng-if,则$scope.formName.$valid将无法工作,而如果您使用ng-show,则$scope.formName.$valid将起作用。 - Vaibhav Shaha
2
这应该是最好的答案,简单明了。但是你能处理表单无效吗?你如何向用户展示哪些输入是无效的? - Nicolas Leucci
1
@ps0604,formName.$valid 只能在模板中访问,如果你想在控制器中访问它,你需要创建一个对象 $scope.forms.formName,并在模板中使用 <form name="forms.formName">查看此评论 - Damsorian
显示剩余3条评论

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
$scope已经过时了,现在我们使用vm方法。您能否使用控制器语法方法创建一个plunker来回答同样的问题?我无法做到这一点。这对其他正在寻找今天上下文答案的人也会有帮助。谢谢。 - ankitd

14

这里有另外一种解决方案:

在你的HTML中设置一个隐藏范围变量,然后你就可以从你的控制器中使用它:

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

Here is the full working example:

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
BusinessCtrlcreateBusinessFormFormController之前初始化。 即使你在表单上使用了ngController,它也不会按照你期望的方式工作。 你无法解决这个问题(你可以创建自己的ngControllerDirective,并尝试欺骗优先级)。这就是angularjs的工作方式。
例如,可以查看此plnkr: http://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview

0
我喜欢在表单无效时禁用保存/提交按钮:
<form name="ruleForm">
    <md-input-container>
        <label>Priority</span>
        <input name="description" ng-model="vm.record.description" required>
    </md-input-container>
    <md-button ng-click="vm.save()" ng-disabled="ruleForm.$invalid" class="md-primary md-raised">Save</md-button>
</form>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接