在Angular实际开发中,我们遇到查询数据,用ng-repeat循环在前台页面展示,而ng-repeat中的内容又需要独立操作,且需对每个ng-repeat中的区域中的输入框进行修改保存,且每个ng-repeat区域都需要校验,此时我们发现校验失效了。
遇到此问题时,当时第一反应是有两处原因,一处是由于ng-repeat中的内容是动态编译出来的,可能是作用域问题导致;另一处是由于我们的校验是通过form来实现的,动态form失效了。
因此,特做了如下小实例进行了验证,发现问题出在动态Form的校验没生效。
首先,让我们来看下动态编译实例:
formValidationTest.html
<html> <head> <title>表单验证</title> <!-- <link href="lib/bootstrap-gh-pages/assets/bootstrap.css" rel="stylesheet" type="text/css" /> --> <link rel="stylesheet" href="lib/bootstrap-3.0.0/css/bootstrap.css"> <style> #css_form input.ng-invalid.ng-dirty { background-color: #FFC0CB; } #css_form input.ng-valid.ng-dirty { background-color: #78FA89; } </style> </head> <body ng-controller="myCtrl"> <div class="panel panel-primary"> <div class="panel-heading"> <div class="panel-title">表单验证</div> </div> <div class="panel-body"> <div class="row"> <div inner-content> </div> </div> </div> </div> <script type='text/javascript' src='lib/angular/angular.js'></script> <script type='text/javascript' src='lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.10.0.js'></script> <script type='text/javascript' src='app.js'></script> <script type='text/javascript' src='directive.js'></script> </body> </html>
subPage.html
<form id="css_form" class="form-horizontal" novalidate name="myform" role="form"> <div class="form-group"> <label for="inputAccount" class="col-md-2 control-label">账号:</label> <div class="col-md-2"> <!--输入框 --> <input type="number" ng-model="user.account" min="3" max="6" name="myAccount" required class="form-control" id="inputAccount" placeholder="请输入3-6的整数"/> </div> <!-- 隐藏块,显示验证信息--> <div class="alert alert-danger well-sm" ng-show="myform.myAccount.$error.required">账号不能为空!</div> <div class="alert alert-danger well-sm" ng-show="myform.myAccount.$error.min || myform.myAccount.$error.max">输入值必须在3-6之间!</div> </div> <div class="form-group"> <label for="inputEmail" class="col-md-2 control-label">邮箱:</label> <div class="col-md-2"> <!--输入框 --> <input type="email" ng-model="user.email" name="myEmail" required class="form-control" id="inputEmail" placeholder="请输入邮箱地址"/> </div> <!-- 隐藏块,显示验证信息--> <div class="alert alert-danger well-sm" ng-show="myform.myEmail.$error.required">邮箱不能为空!</div> <div class="alert alert-danger well-sm" ng-show="myform.myEmail.$error.email">邮箱格式不正确!</div> </div> <!--按钮组--> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button class="btn btn-default" ng-disabled="!myform.$valid">提交</button> <button class="btn btn-default" ng-click="reset(user)">重置</button> </div> </div> </form>
app.js
var myApp=angular.module('myModule', ['ui.bootstrap','directives']); myApp.controller('myCtrl',function($scope){ $scope.user ={id:1, account:undefined, email:undefined}; $scope.reset=function(user){ //表单重置 user.account = ''; user.email = ''; }; }); angular.element(document).ready(function() { angular.bootstrap(document,['myModule']); });
directive.js
'use strict'; /* Directives */ var directivesModule = angular.module( "directives", [] ); directivesModule.directive("innerContent", ['$http','$compile', function($http, $compile) { return { restrict: "A", scope: false, link: function(scope, element, attrs) { var initTpl = function (){ $http.get('subPage.html').success(function(response) { element.html(response); $compile(element, false, 0)(scope); }); }; initTpl(); }, replace: true }; }]);
在FireFox运行效果:
校验生效,说明动态编译对校验是不影响的。修改subPage.html如下:
<form id="css_form" class="form-horizontal" novalidate name="myform_{{user.id}}" role="form"> <div class="form-group"> <label for="inputAccount" class="col-md-2 control-label">账号:</label> <div class="col-md-2"> <!--输入框 --> <input type="number" ng-model="user.account" min="3" max="6" name="myAccount" required class="form-control" id="inputAccount" placeholder="请输入3-6的整数"/> </div> <!-- 隐藏块,显示验证信息--> <div class="alert alert-danger well-sm" ng-show="myform_{{user.id}}.myAccount.$error.required">账号不能为空!</div> <div class="alert alert-danger well-sm" ng-show="myform_{{user.id}}.myAccount.$error.min || myform_{{user.id}}.myAccount.$error.max">输入值必须在3-6之间!</div> </div> <div class="form-group"> <label for="inputEmail" class="col-md-2 control-label">邮箱:</label> <div class="col-md-2"> <!--输入框 --> <input type="email" ng-model="user.email" name="myEmail" required class="form-control" id="inputEmail" placeholder="请输入邮箱地址"/> </div> <!-- 隐藏块,显示验证信息--> <div class="alert alert-danger well-sm" ng-show="myform_{{user.id}}.myEmail.$error.required">邮箱不能为空!</div> <div class="alert alert-danger well-sm" ng-show="myform_{{user.id}}.myEmail.$error.email">邮箱格式不正确!</div> </div> <!--按钮组--> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button class="btn btn-default" ng-disabled="!myform_{{user.id}}.$valid">提交</button> <button class="btn btn-default" ng-click="reset(user)">重置</button> </div> </div> </form>
app.js
var myApp=angular.module('myModule', ['ui.bootstrap','directives']); myApp.controller('myCtrl',function($scope){ $scope.user ={id:1, account:undefined, email:'[email protected]'}; $scope.reset=function(user){ //表单重置 user.account = ''; user.email = ''; }; }); angular.element(document).ready(function() { angular.bootstrap(document,['myModule']); });
在FireFox中运行效果:
发现校验失效了,因此确定是动态form原因造成的。且邮箱输入框能正常显示模型数据,说明双向绑定也是OK的。