欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Angular:表单 有大用

理解 Angular 应用里的表单。

封面摄影:Maciej Bartnicki

来自  来自  https://ninghao.net/course/7668#info


# git branch         #查看当前分支

# git status     #查看状态

# git push origin getting-started 

# git log    #查看提交的日志

# git checkout master     #切换到 master 分支

# git merge getting-started     #合并

# git log    --oneline         #以一行方式查看日志

# git push origin master        #把本地的 master 分支推送到 origin 远程

# git checkout -b forms    #创建分支forms,并切换到forms分支


# ng generate module modules/user    #生成user模块

CREATE src/app/modules/user/user.module.ts (190 bytes)

# ng generate component modules/user/components/register            #生成组件register ,组件放在模块目录的下面吧

CREATE src/app/modules/user/components/register/register.component.html (23 bytes)

CREATE src/app/modules/user/components/register/register.component.spec.ts (613 bytes)

CREATE src/app/modules/user/components/register/register.component.ts (283 bytes)

CREATE src/app/modules/user/components/register/register.component.css (0 bytes)

UPDATE src/app/modules/user/user.module.ts (293 bytes)        #生成组件后会自动更新相应的模块





介绍与准备 

1)介绍(表单)

创建一个 User 模块,在模块里添加一个注册用户用的组件,然后再去了解一下 Angular 的 Reactive 类型的表单。把创建的 FormControl 使用指令绑定在视图里的表单元素上。了解一下怎么管理表单元素的值,比如订单表单元素的值的变化,在组件里直接设置它的值。

再看一下 FormGroup,表单群组,一个群组里可以包含多个 FormControl。提交表单会触发特定的事件,我们可以监听这个事件。

在 FormControl 的上面可以再添加一个验证的方法,利用表单状态的 CSS 类可以定制表单元素在不同状态下的样式。

来自  https://ninghao.net/video/7670#info

2)准备项目

在终端,先查看一下项目当前的分支,显示是在 getting-started 这个分支上,这是我们之前给项目添加的一个分支,可以再查看一下在这个分支上做的提交,

# git log --oneline

最后一次提交的日志是 Services 。

切换到 master 分支,

# git checkout master

在这个分支上去做一次合并,要合并的是 getting-started 分支。

# git merge getting-started

合并之后可以再查看一下 master 分支上的提交,

# git log --oneline

最后一次提交的日志也会是 Services。

下面可以把本地的 master 分支推送到 origin 远程,

# git push origin master

然后可以再推送一下 getting-started 远程。

# git push origin getting-started

再去创建一个分支并且切换到这个分支上,

# git checkout -b forms

创建一个要 forms 的分支,并且把项目当前的分支切换到 forms 。

再把刚才创建的 forms 分支推送到 origin 远程的上面,

# git push origin forms

在这个课程里我对项目的修改都会保存在这个分支上,到时候你可以找到项目的远程,查看一下我在这个分支上做的提交。

来自  https://ninghao.net/video/7671#info

3)创建 User 模块与 Register 组件

先在项目里添加一个模块,用 ng 命令,generate 一个 module,放在 modules 目录的下面,模块的名字叫 user 。

# ng g m modules/user  (  ng generate module modules/user   )

再生成一个组件,ng generate 一个 component ,放在 modules/user/components ,名字是 register 。

# ng g c modules/user/components/register  (  ng generate component modules/user/components/register  )

回到项目,打开 AppRoutingModule,在 routes 里面再添加一条路由,路由的地址是 register,对应的 component 是 RegisterComponent 。

然后打开应用的根模块,AppModule,在这个模块的 imports 里面得把一开始我们创建的 UserModule 添加进来。

回到浏览器,访问一下 register 这个地址,页面上显示这行文字就是 UserModule 模块里的 Register 组件要显示的内容 。

来自  https://ninghao.net/video/7672#toc

表单 

4)表单(Reactive Forms)

Angular 提供了两种风格的表单,一种是 Reactive Forms (响应式表单),还有一种是 Template-driven  (模板驱动类型的表单) 类型的表单。下面我们要介绍使用的是 Reactive Forms。

要使用这种类型的表单,需要在模块里导入 ReactiveFormModule,我打算要之前创建的 Register 组件里创建一个这样的表单,这个组件属于 UserModule 模块,所以要在这个模块里导入 ReactiveFormsModule。

打开 UserModule,先在文件的顶部,从 @angular/forms 这个包里面,导入一个 ReactiveFormsModule 。

然后在模块的 imports 里面,添加一个 ReactiveFormsModule,这个模块来自 @angular/forms 这个包。

FormControl

然后打开 RegisterComponent 组件,在组件里可以先添加一些 FormControl,然后在把它们绑定在组件的视图上使用。比如添加一个 username 属性,它的值新建一个 FormControl,这个 FormControl 来自 @angular/forms 包。

[FormControl]

有了这个 FormControl 实例以后就可以把它绑定在视图上使用,打开这个组件的模板文件,先添加一组 label,标签。标签文字用一组段落标签包含一下,文字是 Username 。

然后添加一个 input 元素,类型是 text,在这个元素上可以绑定在组件里创建的 username,这里需要用 formControl 指令,它的值是 username 。这个 username 就是在 Register 组件里的一个 FormControl 实例。

预览

回到浏览器,预览一下,打开 register 这个地址,页面上会显示一个文本类型的表单元素。

来自  https://ninghao.net/video/7674#info

5)管理表单元素的值

在组件的模板里可以访问 FormControl 的 value 属性,获取到它的当前的值。打开 RegisterComponent 的模板文件,在这个 Username 标签文字的右边,用插值的形式绑定输出一个 username 的 value 属性的值。

回到浏览器,在这个文本框里输入点东西,你会发现在绑定输出了 username.value 的地方,会显示文本框里的当前的值。

valueChanges

在组件里面,我们也可以得到使用视图里的文本框输入的值,FormControl 实例上的 valueChanges 属性是个 Observable,在这个 Observable 上,可以得到 FormControl 的每次发生变化的值。

回到组件,在组件的 ngOnInit 生命周期方法里,订阅一下 username 的 valueChanges 这个 Observable,this.username.valueChanges,用一下 subscribe ,提供一个方法参数,这个方法就是 Observable 有值的时候要做的事情。

方法接收一个 value 参数,在方法里用一个 console.log,输出 Username: 加上 value 的值。

预览

再到浏览器上试一下,在这个文本框里输入点东西,文本框的值有变化,我们在组件里订阅了这个变化,要做的事情就是在控制台上输出一个 Username ,然后是发生变化的值。

setValue

在组件里可以使用 FormControl 实例的 setValue 设置它的值。在这个 ngOnInit 里面,再用一下 this.username.setValue,把要设置的值交给这个方法,比如 bruce_wang。

现在,文本框上会显示在组件里使用 setValue 设置的这个值。

来自  https://ninghao.net/video/7675


6)表单元素群组(FormGroup)

一个 FormGroup 里面可以包含一组 FormControl,就相当于是在一个表单里面有多个表单元素。回到项目,打开 RegisterComponent 组件。

在这个组件里可以添加一个 FormGroup,名字是 registerForm,它的值新建一个 FormGroup,这个 FormGroup 来自 @angular/forms 包。给它提供一个对象参数,在这个对象里可以添加一些 FormControl。

比如添加一个 username,它的值新建一个 FormControl,下面再添加一个 password,它的值也是新建一个 FormControl 实例。

之前添加的这个 username 现在可以去掉了。

valueChanges

在 ngOnInit 生命周期方法里,之前订阅了一下 username 的 valueChanges 这个 Observable,FormGroup 也有这个 Observable,把 username 换成 registerForm,它是一个 FormGroup。

表单群组的值有变化,可以在控制台上输出一个 Register,后面加上 value 的值。

setValue

我们也可以使用表单群组上的 setValue 去设置表单的值,用一下 this.registerForm 的 setValue,它的值现在是一个对象,里面添加一个 username,设置一下表单里的 username 的值。再添加一个 password,设置一下表单里的 password 这个 FormControl 的值。 如果只想设置部分的表单元素的值,可以用一下 patchValue

模板

下面再去处理一下组件的视图,在视图里现在可以添加一个 form 元素,在这个表单元素上面,用一个 formGroup 指令,绑定一个 registerForm 这个 FormGroup 。

这个表单里有一个 username 元素,元素上现在可以使用一个 formControlName 指令,在这个元素上绑定 formGroup 里的一个 formControl,这里就是 username 。 因为这个username的值是一个字符串类型的值,所以使用formControlName 指令的时候,并没有使用方括号

再添加一个表单元素,一组 label 标签,标签文字是 Password,然后再添加一个 input 元素,元素的类型是 password,在这个元素上用一下 formControlName 指令,绑定的 formControl 就是 registerForm 里的 password 。

预览

回到浏览器,可以预览一下,现在页面上会显示一个表单,里面有两个表单元素,一个 username,还有一个 password。我们在组件里设置了这两个元素的值,同时也订阅了这个表单的值的变化。表单里的任何一个元素的值发生变化,暂时我们要做的事情就是在控制台上输出变化的值。

来自   https://ninghao.net/video/7676#info


7)提交表单(ngSubmit)

提交表单会触发一个 submit 事件,FormGroup 指令会监听 form 元素的 submit 事件,发生这个事件它会触发一个 ngSubmit 事件,我们可以监听一下这个事件,也就可以在用户提交表单以后去做一些事情。

回到项目,打开 RegisterComponent 组件,可以先在组件里添加一个事件处理方法,名字可以叫它 onSubmit,在这个方法里要做的事情还是简单的在控制台上输出点东西,输出一个 Submit,然后再加上 this.registerForm.value,也就是 registerForm 的当前的值。

打开组件的模板文件,在使用了 formGroup 指令的这个 form 元素上,绑定一个 ngSubmit 事件,事件的处理方法用一下组件里的 onSubmit() 。

Submit button

在这个表单里可以再添加一个提交按钮,一组 button 元素,按钮的 type 设置成 submit,按钮文字是 Submit 。

预览

回到浏览器试一下,按一下表单里的这个 Submit 按钮,点击这个按钮,会在这个表单上触发一个 submit 事件,formGroup 也就会触发 ngSubmit 事件,我们监听了这个事件,要做的事情就是在控制台上输出表单的当前的值。

来自  https://ninghao.net/video/7677#info


8)验证表单(Validators)

表单元素上面可以添加一些验证的规则,比如标记表单元素是必填的项目,或者表单的值是 email,规定最小或最大长度等等。

回到项目,先打开 RegisterComponent 组件,先从 @angular/forms 包里面,把 Validators 导入进来用一下。然后在这个 FormGroup 里的这两个 FormControl 的上面,添加点验证规则。

这个 FormControl 的第一个参数是这个表单元素的初始值,如果没有可以用一个空白,它的第二个参数就是一些 validator,也就是验证的规则,可以是一个,也可以是多个规则,如果是多个规则 ,可以把它们放在一个数组里。

这里用一个 Validators.required,表示这个 FormControl 是必填项。

在这个 password 上面,也添加一条规则,用一下 Validators.minLength 设置一下最小长度,把它设置成 6 。

statusChanges

在组件的 ngOnInit 里面,可以订阅一下表单的状态的变化,用一下 this.registerForm 上的 statusChanges ,它是一个 Observable,用 subcribe 订阅一下它,提供一个方法参数,方法有个 status 参数,方法做的事情可以在控制台上输出点东西,Stauts,后面再加上表单的状态。

模板

打开组件的模板文件,在这里我们也可以输出一下这个表单的状态,放在一组 pre 标签里面,Status,然后再绑定输出 registerForm 上的 status。

预览

回到浏览器,可以再预览一下。现在组件上显示的这个表单的状态是 VALID,表示这是一个有效的表单,也就是表单里的元素的值可以通过我们给它们设置的验证规则。

下面修改一下表单元素的值,去掉 Username 里的值,这样表单的状态会变成 INVALID,因为 Username 是一个必填的项目。输入一个值,状态又会是 VALID,因为我们在组件里也订阅了这个表单的状态的变化,发生变化做的事情就是在控制台上输出这个状态。

修改一下 Password ,减小一位,因为在这个 Password 元素上我们设置的验证规则是元素的值的长度不能小于 6,所以它的长度小于 6,表单的状态也就会是 INVALID,修改一下 password 的值,表单通过验证,状态又会变成 VALID。

来自  https://ninghao.net/video/7678#info

9)表单元素类(.ng-valid, .ng-invalid, .ng-touched...)

在 RegisterComponent 组件里面,暂时先注释掉设置表单值的这几个代码。回到浏览器,然后打开浏览器的开发者工具,检查一下页面上的表单元素,你会发现在表单元素上会有一些 ng 开头的 css 类,这些类就是表示的表单元素的一些状态

现在这个元素上有 ng-untouched,如果还没有动过表单元素,就会出现这个类,动过以后,这个类会变成 ng-touched。

鼠标选中这个文本框,然后再离开文本框。你会发现 ng-untouched 类立即就变成了 ng-touched。 现在这个表单元素上还有一个 ng-pristine,意思是在这个文本框里现在还没有输入内容。另外还有一个 ng-invalid,表示这个表单元素没有通过验证。

选中文本框,输入点内容,现在元素上的 ng-pristine 立即就变成了 ng-dirty,表示元素的值发生了变化。另外 ng-invalid 也表示变成了 ng-valid,表示表单元素通过了我们设置的验证规则。

样式

在组件的样式表里可以使用这些类去添加点样式。先回到组件,找到 password 这个 FormControl ,给它再添加一条验证规则,如果有多条验证规则可以把它们放在一个数组里,然后在数组里再添加一个 Validators.required ,表示这也是一个必填的项目。

然后打开组件的样式表,样式选择器设置成 input.ng-invalid 同时包含 ng-touched ,设置一下这类元素的 border 属性,给它添加一条红色的边框。这条样式的意思就是,如果元素被动过了,但是没有通过验证,就在元素的周围添加一条红色的边框。

预览

回到浏览器预览一下,选中 Username,然后离开,文本框的周围会出现一条红色的边框,在这个文本框里再输入点内容,元素通过了验证,也就会去掉它的红色边框的样式。

再试一下 Password 字段,选中它,然后离开,元素出现红色边框,在这个 Password 里输入点内容,通过验证以后,红色边框就会不见了。

来自  https://ninghao.net/video/7679#info

10)表单构建器(formBuilder)

Angular Forms 里面有一个 FormBuilder,使用它可以更方便的去创建需要的表单。回到项目,打开 RegisterComponent 组件,在组件里先从 @angular/forms 里面,把 FormBuilder 导入进来用一下。

这个 FormBuilder 是个 Service ,可以把它作为这个组件的依赖注入进来,这样就可以使用这个服务上提供的方法去创建表单了。在组件的构造方法里,添加一个 private formBuidler,类型是 FormBuilder。

现在我们就可以使用组件的 formBuidler 这个属性上的一些方法去创建表单了。先注释掉之前创建的这个 registerForm,重新再添加一个 registerForm,它的值用一下 this.formBuilder,它上面有几个方法可以创建不同的东西,比如 control,可以创建 FormControl,group 可以创建 FormGroup,还有 array,可以创建 FormArray。

这里我们要创建的是一个 FormGroup,所以用一下它上面的 group 方法,给它提供一个对象参数,里面定义这个 FormGroup 里需要的 FormControl。添加一个 username,它的值是一个数组,第一个参数是它的初始化,第二个参数是验证的方法,添加一个 Validators.required 。

下面再添加一个 password,一个数组,初始值是空白,验证方法有两个,放在一个数组里,添加一个 Validators.required,还有一个 Validators.minLength ,最小长度设置成 6。

预览

回到浏览器再预览一下,现在页面上显示的这个表单,它的功能跟之前是一样的。只不过现在它用的 FormControl 实例是我们用 FormBuilder 服务创建的。

来自  https://ninghao.net/video/7680#info






普通分类: