Angular模版驱动表单的使用总结


Posted in Javascript onMay 05, 2018

表单的重要性就不多说了,Angular支持表单的双向数据绑定,校验,状态管理等,总结下。

获取用户输入

<div class="container-fluid login-page">
 <h1>Angular表单</h1>
 <form class="login-area">
  <div class="form-group">
    <input class="form-control" type="text" name="name" id="login-name" placeholder="请输入登录帐号">
  </div>
  <div class="form-group">
   <input class="form-control"type="password" name="pwd" id="login-pwd" placeholder="请输入登录密码">
  </div>
  <div class="form-group">
   <button type="submit" class="btn btn-block btn-success">登录</button>
  </div>
 </form>
</div>

假如有以上简单表单,先不论优劣,有哪些方式可以获取到表单数据呢? 先看两种简单粗暴的

1)事件$event的方式

在监听事件的时候,将整个事件载荷 $event 传递到事件处理函数,它会携带触发元素的各种信息。这里监听form元素的submit事件,将整个form的信息传给处理函数,并打印出来

<form class="login-area" (submit)="testInput($event)">
testInput ( _input: any) {
  console.dir(_input);
}

触发submit后,查看结果。非常眼熟,就是传统方式中的event嘛,后面就不用多说了,target即为form元素,再定位到input子元素,分别获取value即可。

Angular模版驱动表单的使用总结

为了获取input的Value,我们传递了非常多的无用信息,处理函数根本就不关心元素的位置,属性等等,它只需要value值。所以这种方式不可取

2) 模版引用变量

Angular中可以用 模版引用变量(#var)来引用DOM元素/Angular组件/指令。通常模版引用变量就是代表声明的那个元素,当然也可以修改指向,可以代表Angular指令(比如后续用到的ngForm指令和ngModel指令)。

// 模版引用变量代表Form元素
<form class="login-area" #test (submit)="testInput(test)">

// 模版引用变量代表ngForm指令
<form class="login-area" #test="ngForm"(submit)="testInput(test)">

从下图可以看到不同,第一个和$event.target一样,是DOM元素;第二个是ngForm指令,可以跟踪每个控件的值和状态(是否输入过?是否校验通过?等等),后续会详细说

Angular模版驱动表单的使用总结

所以当我们直接用模版引用变量引用input元素时,就可以直接在模版中传递input元素的value,而不需要传递整个元素信息。这种方式也不好,必须要通过事件触发才可以传递

<form class="login-area" (submit)="testInput(test.value)">
  <div class="form-group">
    <input class="form-control" #test type="text" name="name" id="login-name" placeholder="请输入登录帐号">
  </div>

注意:模版引用变量的作用域是整个模版,所以在同一个模版中,不能有同名的模版引用变量

这两种获取表单数据的方式只是了解下,因为Angular提供了两种更好的构建表单的方式---模版驱动表单和模型驱动表单

模版驱动表单

顾名思义,是使用 HTML模版 + 表单专业指令 来构建表单。使用模版驱动表单,记得要先在应用模块中import FormsModule。说明以下几点:

1、模版驱动表单使用 [(ngModel)] 语法进行双向数据绑定,非常简单就可以把表单数据绑定到模型中。注意在表单中使用[ngModel]时,必须要定义name属性,因为Angular在处理表单时,会创建一些FormControl,用来跟踪单个表单控件的值和状态,而表单控件name属性就是键值,所以必须要指定name属性。(这应该算是指出了获取表单数据的两种科学的方式:[ngModel]语法绑定 和 通过formControl的Api获取)

2、使用 ngForm指令,来监听整个表单的有效性(valid属性)。Angular会自动为form表单自动创建并添加ngForm指令,直接使用即可

3、使用ngModel指令,来监听单个表单控件的状态,还会使用特定的Angular css来更新控件样式 ,我们可以通过这些class来控制不同状态时,表单控件的展示 

Angular模版驱动表单的使用总结

4、表单验证可以使用 HTML原生的表单验证属性(required , pattern , max , min 等等) ,验证出错时,3中提到的errors属性就会有对应的错误项;

还可以自定义验证器,因为模版驱动表单不直接访问FormControl实例,所以需要把自定义的验证器用指令包装。

通过以下栗子来展示模版驱动表单简单使用

<!-- 模版引用变量指向ngForm指令 -->
 <form class="login-area" #testform="ngForm" (submit)="testInput()">
  <div class="form-group">
    <!-- ngModel绑定数据 -->
    <!-- required 和 pattern 指定校验规则 -->
    <!-- 模版引用变量指向ngModel指令 -->
    <input class="form-control" type="text" name="name" id="login-name" placeholder="请输入登录帐号"
        [(ngModel)] = "user.name"  
        required
        pattern="[0-9A-z]+"
        #nameinput = "ngModel"
        >
  </div>
    <!-- 通过表单控件的状态控制是否展示错误说明及展示何种错误说明 -->
  <div class="form-group" *ngIf="nameinput.touched&&nameinput.invalid">
    <span class="error-info" *ngIf="nameinput.errors?.required">用户名不能为空!</span>
    <span class="error-info" *ngIf="nameinput.errors?.pattern">用户名只能包含英文或数字!</span>
  </div>
  <div class="form-group">
   <input class="form-control" type="password" name="pwd" id="login-pwd" placeholder="请输入登录密码"
       [(ngModel)] = "user.pwd"
       required
       #pwdinput = "ngModel">
  </div>
  <div class="form-group" *ngIf="pwdinput.touched&&pwdinput.invalid">
   <span class="error-info" *ngIf="pwdinput.errors?.required">密码不能为空!</span>
  </div>
  <div class="form-group">
   <!-- 通过表单的状态控制按钮是否可用 -->
   <button type="submit" class="btn btn-block btn-success" [disabled]="testform.invalid">登录</button>
  </div>
 </form>

通过Angular css 自动添加的class来控制表单样式

input.ng-invalid.ng-touched{
    border: 2px solid red;
 }

查看下效果,表单校验、样式反馈、按钮状态管理、数据获取都很方便。

Angular模版驱动表单的使用总结

至于如何自定义验证器会和模型驱动表单的自定义验证器一起说明,那就是下一篇了;随笔中有不足的欢迎大家指正···

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
驱动事件的addEvent.js代码
Mar 27 Javascript
getElementsByTagName vs selectNodes效率 及兼容的selectNodes实现
Feb 26 Javascript
javascript动画之圆形运动,环绕鼠标运动作小球
Jul 20 Javascript
jQuery中:not选择器用法实例
Dec 30 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
Nov 29 Javascript
AngularJS内建服务$location及其功能详解
Jul 01 Javascript
AngularJS开发教程之控制器之间的通信方法分析
Dec 25 Javascript
原生js实现下拉框功能(支持键盘事件)
Jan 13 Javascript
微信小程序 支付后台java实现实例
May 09 Javascript
vuejs+element-ui+laravel5.4上传文件的示例代码
Aug 12 Javascript
详解JavaScript的BUG和错误
May 07 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
Feb 28 Javascript
浅谈Angular HttpClient简单入门
May 04 #Javascript
Vue项目全局配置微信分享思路详解
May 04 #Javascript
vue嵌套路由与404重定向实现方法分析
May 04 #Javascript
Vue.js最佳实践(五招助你成为vuejs大师)
May 04 #Javascript
详解使用jQuery.i18n.properties实现js国际化
May 04 #jQuery
node实现的爬虫功能示例
May 04 #Javascript
基于jQuery.i18n实现web前端的国际化
May 04 #jQuery
You might like
PHP中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
php连接oracle数据库的核心步骤
2016/05/26 PHP
YII框架批量插入数据的方法
2017/03/18 PHP
php实现有序数组旋转后寻找最小值方法
2018/09/27 PHP
JavaScript Archive Network 集合
2007/05/12 Javascript
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
实现点击列表弹出列表索引的两种方式
2013/03/08 Javascript
用javascript替换URL中的参数值示例代码
2014/01/27 Javascript
js从Cookies里面取值的简单实现
2014/06/30 Javascript
jQuery窗口、文档、网页各种高度的精确理解
2014/07/02 Javascript
JavaScript中使用Math.floor()方法对数字取整
2015/06/15 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
2015/08/21 Javascript
js实现随机抽选效果、随机抽选红色球效果
2017/01/13 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
JAVA中截取字符串substring用法详解
2017/04/14 Javascript
12条写出高质量JS代码的方法
2018/01/07 Javascript
实例讲解vue源码架构
2019/01/24 Javascript
详解如何搭建mpvue框架搭配vant组件库的小程序项目
2019/05/16 Javascript
jQuery Ajax async=&gt;false异步改为同步时,解决导致浏览器假死的问题
2019/07/22 jQuery
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[38:31]完美世界DOTA2联赛PWL S3 Magma vs GXR 第一场 12.13
2020/12/17 DOTA
用Python进行行为驱动开发的入门教程
2015/04/23 Python
Python迭代和迭代器详解
2016/11/10 Python
Python变量和数据类型详解
2017/02/15 Python
TensorFlow的权值更新方法
2018/06/14 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
python如何通过pyqt5实现进度条
2020/01/20 Python
Omio意大利:全欧洲低价大巴、火车和航班搜索和比价
2017/12/02 全球购物
英国运动服、设备及配件网站:DW Sports
2019/12/04 全球购物
接口中的方法可以是abstract的吗
2015/07/23 面试题
渗透攻击的测试步骤
2014/06/07 面试题
小学敬老月活动方案
2014/02/11 职场文书
主管会计岗位职责
2014/03/13 职场文书
会计学自荐信
2014/06/03 职场文书
校庆口号
2014/06/20 职场文书
纪念九一八事变演讲稿:青少年应树立远大理想
2014/09/14 职场文书