在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:'baa@126.com'}; $scope.reset=function(user){ //表单重置 user.account = ''; user.email = ''; }; }); angular.element(document).ready(function() { angular.bootstrap(document,['myModule']); });
在FireFox中运行效果:
发现校验失效了,因此确定是动态form原因造成的。且邮箱输入框能正常显示模型数据,说明双向绑定也是OK的。