AngularJs进阶-表单与验证
修真院Web工程师零基础全能课
本节课内容
AngularJs进阶-表单与验证
主讲人介绍
沁修,葡萄藤技术总监
项目经验丰富,擅长H5移动项目开发。
专注技术选型、底层开发、最佳代码实践规范总结与推广。
直播录屏版
传送门:https://v.qq.com/x/page/k0705yf7g0g.html
文字解析版
大纲概述
简单表单
增加css的表单
验证
自定义验证
在angularjs的开发中有一项必不可少的内容就是表单。
表单里有大量控件,如input,radio,select等,表单就是这些控件的集合,可以将相关的控件根据需要进行分组。
简单表单
在过去的表单开发中往往是这样:
需要给每一个控件添加一个id,然后找到id所在的DOM,对DOM绑定一些事件,来处理用户的操作,以及及时给予反馈。
但在angularjs中,我们有双向数据绑定的ngModel:
它提供了model和view之间的双向数据绑定,大大的减轻了开发的工作量。
而且,ng中的form已经不是普通的form了,是一个被ng封装过的指令:
可以完成普通form无法实现的功能,自带强大的验证功能。我们直接来段简单表单的代码:
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidate> <!— 会阻止默认的html5验证,因为效果实在不是很好,我们希望自己来控制这一切。 —>
名字:<inputng-model="user.name"type="text"><br/>
Email:<inputng-model="user.email"type="email"><br/>
性别:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()">还原上次保存</button>
<buttonng-click="update(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
});
</script>
// 不合法的值是不会进入user的
ngModel是表单中的核心指令,同时也是一个使用频率非常非常高的指令:
它不止提供了数据绑定,还有验证,样式更新,数据格式化,编译功能。
如果不设置ngModel,那么angluar就无法知道form.$valid的值是否为真。
它的input控件自带一些验证选项:
<input
ng-model=""
[name=""]
[required=""]
[ng-required=""]
[ng-minlength=""]
[ng-maxlength=""]
[ng-pattern=""]
[ng-change=""]>
...
</input>
加上样式的表单
ng在验证输入或表单的有效性的时候已经提供了一些默认类。
因此可以编辑自己喜欢的的css,私有化的定制这些类来实现特定的场景应用
.ng-valid { }
.ng-invalid { }
.ng-pristine { }
.ng-dirty { }
/* really specific css rules applied by angular */
.ng-invalid-required { }
.ng-invalid-minlength { }
.ng-valid-max-length { }
那么改造一下刚刚那个表单,让它交互性更强:
<styletype="text/css">
input.ng-invalid.ng-dirty {
background-color:#fa787e;
}
input.ng-valid.ng-dirty {
background-color:#78fa89;
}
</style>
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidate>
名字:<inputng-model="user.name"type="text"required><br/>
Email:<inputng-model="user.email"type="email"required><br/>
性别:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()">还原上次保存</button>
<buttonng-click="update(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
});
</script>
表单与控制器
在angualrjs中,ng-controller作用域当中的form表单,可以使用name属性将它暴露到scope中。
我们再次来改造一下这个表单,给它加上一些简单的验证,要求是:
name必填
email必填
表单保存过就不能再保存
表单和保存的内容一致就无法再保存
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidatename="formName">
名字:<inputng-model=“user.name” name=“userName" type="text"required><br/>
<divng-show="formName.userName.$dirty&&formName.userName.$invalid">
<span>请填写名字</span>
</div>
Email:<inputng-model=“user.email” name=“emailName"type="email"required><br/>
<divng-show="formName.userEmail.$dirty && formName.userEmail.$invalid">提示:
<spanng-show="formName.userEmail.$error.required">请填写Email</span>
<spanng-show="formName.userEmail.$error.email">这不是一个有效的Email</span>
</div>
性别:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()"ng-disabled="isUnchanged(user)">还原上次</button>
<buttonng-click="update(user)"ng-disabled="formName.$invalid || isUnchanged(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
$scope.isUnchanged=function(user) {
returnangular.equals(user,$scope.data);
};
});
事实上是这样的,ng的表单提供了很多属性来帮助我们验证它
属性class说明$validng-valid验证是否通过$invalidng-invalid验证是否未通过$pristineng-pristine表单和控件是否没使用过$dirtyng-dirty表单和控件是否使用过
如果我们要访问表单属性就可以:
form-name.angular-property
如果是访问输入框属性则可以:
form-name.input-name.angular-property
如果想禁用表单按钮,非常简单,如果整个表单没通过验证,就会禁用,那就只需要加上这样的代码
ng-disabled="formName.$invalid”
这也说明,我们input和form的name字段是必须加的,需要通过这样的链式调用法访问到属性。
更漂亮的验证
如果我们给我们的网站加上bootstrap,就可以使用它提供的类,来围绕我们的表单做更好看的信息和颜色了。
这个时候我们会用到ng-class,它允许我们基于一个表达式来添加类。
比如如果输入框的状态是$invalid或者不是$pristine的话,我们想要添加一个has-error类,就可以这样:
ng-class=“{<class>: <express>}"
<!-- USERNAME -->
<divclass="form-group"ng-class="{ 'has-error' : userForm.username.$invalid && !userForm.username.$pristine }">
<label>Username</label>
<inputtype="text"name="username"class="form-control"ng-model="user.username"ng-minlength="3"ng-maxlength="8">
<png-show="userForm.username.$error.minlength"class="help-block">Username is too short.</p>
<png-show="userForm.username.$error.maxlength"class="help-block">Username is too long.</p>
</div>
<!-- EMAIL -->
<divclass="form-group"ng-class="{ 'has-error' : userForm.email.$invalid && !userForm.email.$pristine }">
<label>Email</label>
<inputtype="email"name="email"class="form-control"ng-model="user.email">
<png-show="userForm.email.$invalid && !userForm.email.$pristine"class="help-block">Enter a valid email.</p>
</div>
自定义的验证
ng为表单验证默认提供了一些directive,比如:
required,pattern,minlenth,maxlength,min,max。
但我们可以通过定义这些指令增加验证规则。这些指令写起来很好玩,同时它们也有一些规则需要掌握:
1.model更新到view的时候。
model发生的改变,都在ngModelController.$formatters数组中排队执行,然后通过$setValidity去修改控件的验证状态
2.view更新到model的时候。
是这样的,当用户和控件发生交互,会触发$setViewValue。
然后就需要执行$parsers数组中的方法,去从控件中得到值,然后进行过滤或转换或验证。
<divclass="ng-cloak">
<formnovalidateclass="css-form"name="formName">
<div>
大小(整数 0 - 10):<inputintegertype="number"ng-model="size"name="size"min="0"max="10"/>{{size}}<br/>
<spanng-show="formName.size.$error.integer">这不是一个有效的整数</span>
<spanng-show="formName.size.$error.min || formName.size.$error.max">
数值必须在0到10之间
</span>
</div>
<div>
长度(浮点数):
<inputtype="text"ng-model="length"name="length"smart-float/>
{{length}}<br/>
<spanng-show="formName.length.$error.float">这不是一个有效的浮点数</span>
</div>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
varINTEGER_REGEXP=/^\-?\d*$/;
app.directive("integer",function() {
return{
require:"ngModel",
link:function(scope,ele,attrs,ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if(INTEGER_REGEXP.test(viewValue)) {
ctrl.$setValidity("integer",true);
returnviewValue;
}else{
ctrl.$setValidity("integer",false);
returnundefined;
}
});
}
};
});
varFLOAT_REGEXP=/^\-?\d+(?:[.,]\d+)?$/;
app.directive("smartFloat",function() {
return{
require:"ngModel",
link:function(scope,ele,attrs,ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if(FLOAT_REGEXP.test(viewValue)) {
ctrl.$setValidity("float",true);
returnparseFloat(viewValue.replace(",","."));
}else{
ctrl.$setValidity("float",false);
returnundefined;
}
});
}
}
});
</script>
以上就是上节课的内容解析啦
职业选择、求职辅导、学习规划、困难答疑、技术交流等,可以加IT交流群828691304
欢迎访问我们的官网:技能树.IT修真院
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,学习的路上不再迷茫。
这里是技能树.IT修真院,初学者转行到互联网行业的聚集地。"