加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular6 响应式自定义表单控件—注册头像实例

发布时间:2020-12-17 07:03:13 所属栏目:安全 来源:网络整理
导读:1. 组件继承ControlValueAccessor,ControlValueAccessor接口需要实现三个必选方法 writeValue() 用于向元素中写入值,获取表单的元素的元素值 registerOnChange() 设置一个当控件接受到改变的事件时所要调用的函数;这也是我们把变化 emit 回表单的机制;

1. 组件继承ControlValueAccessor,ControlValueAccessor接口需要实现三个必选方法

writeValue()  用于向元素中写入值,获取表单的元素的元素值
registerOnChange()设置一个当控件接受到改变的事件时所要调用的函数;这也是我们把变化 emit 回表单的机制;
registerOnTouched() 设置一个当控件接受到 touch 事件时所要调用的函数
export class ImageListSelectComponent implements ControlValueAccessor {

  _onChange = (_:any)=>{};

  writeValue(obj: any): void{
    this.selectedImg = obj;
  }
  registerOnChange(fn: (_: any) => void): void {
    this._onChange = fn;
  }

  registerOnTouched(fn: any): void {
  }

}

2.??一个的 token 是 NG_VALUE_ACCESSOR 。这是将控件本身注册到 DI 框架成为一个可以让表单访问其值的控件。

但问题来了,如果在元数据中注册了控件本身,而此时控件仍未创建,这怎么破?这就得用到 forwardRef 了,这个函数允许我们引用一个尚未定义的对象。

另外一个 NG_VALIDATORS 是让控件注册成为一个可以让表单得到其验证状态的控件

providers:[
    {
      provide:NG_VALUE_ACCESSOR,useExisting:forwardRef(()=>ImageListSelectComponent),multi:true
    },{
      provide:NG_VALIDATORS,multi:true
    }
  ]

3.?控件的验证器函数(必写方法,否则会报错)

validate(c:FormControl):{[key:string]:any}{
    return this.selectedImg ? null :{
      imageListNotValid:true
    }
  }

4. 表单控制器命名formControlName="avatar"

      <app-image-list-select
          [cols]="‘6‘"
          [rowHeight]="‘1:1‘"
          [items]=‘items‘
          [title]="‘选择头像:‘"
          formControlName="avatar">
          </app-image-list-select>

完整代码:

app-image-list-select.component.ts
 1 import { Component,Input,forwardRef } from ‘@angular/core‘;
 2 import { ControlValueAccessor,NG_VALUE_ACCESSOR,NG_VALIDATORS,FormControl } from ‘@angular/forms‘;
 3 
 4 @Component({
 5   selector: ‘app-image-list-select‘, 6   templateUrl: ‘./image-list-select.component.html‘, 7   styles: [], 8   providers:[
 9     {
10       provide:NG_VALUE_ACCESSOR,11       useExisting:forwardRef(()=>ImageListSelectComponent),12       multi:true
13     },14     {
15       provide:NG_VALIDATORS,16       useExisting:forwardRef(()=>ImageListSelectComponent),17       multi:true
18     }
19   ]
20 })
21 export class ImageListSelectComponent implements ControlValueAccessor {
22 
23   @Input() cols=6;
24   @Input() rowHeight=‘1:1‘;
25   @Input() items:string[]=[];
26   @Input() title = ‘选择‘;
27   selectedImg:string;
28 
29   _onChange = (_:any)=>{};
30 
31   constructor() { }
32 
33   writeValue(obj: any): void{
34     console.log(obj);
35     this.selectedImg = obj;
36   }
37   registerOnChange(fn: (_: any) => void): void {
38     this._onChange = fn;
39   }
40 
41   registerOnTouched(fn: any): void {
42   }
43 
44   validate(c:FormControl):{[key:string]:any}{
45     return this.selectedImg ? null :{
46       imageListNotValid:true
47     }
48   }
49 
50   changeSelected(index){
51     this.selectedImg = this.items[index];
52     this._onChange(this.selectedImg);
53   }
54 
55 }

app-image-list-select.component.html
1 <div>
2   <h3>{{title}}</h3>
3   <mat-icon [svgIcon]=‘selectedImg‘></mat-icon>
4 </div>
5 <mat-grid-list [cols]="cols" [rowHeight]="rowHeight">
6   <mat-grid-tile *ngFor="let item of items;let i = index">
7     <mat-icon [svgIcon]=‘item‘ (click)="changeSelected(i)"></mat-icon>
8   </mat-grid-tile>
9 </mat-grid-list>

register.component.html引用自定义表单控件app-image-list-select

 1 <div class="login-wrap">
 2   <form [formGroup]="myGroup" (ngSubmit)="onSubmit(myGroup,$event)">
 3     <mat-card class="example-card">
 4       <mat-card-header><mat-card-title>注册</mat-card-title></mat-card-header>
 5       <mat-card-content>
 6         <mat-form-field>
 7           <input matInput placeholder="您的email" formControlName="email">
 8         </mat-form-field>
 9         <mat-form-field>
10           <input matInput placeholder="您的姓名" formControlName="username">
11         </mat-form-field>
12         <mat-form-field>
13           <input matInput placeholder="您的密码" formControlName="password">
14         </mat-form-field>
15         <mat-form-field>
16           <input matInput placeholder="请重新输入密码" formControlName="repassword">
17         </mat-form-field>
18         <div>
19           <app-image-list-select
20           [cols]="‘6‘"
21           [rowHeight]="‘1:1‘"
22           [items]=‘items‘
23           [title]="‘选择头像:‘"
24           formControlName="avatar">
25           </app-image-list-select>
26         </div>
27       </mat-card-content>
28       <mat-card-actions>
29         <button mat-raised-button type="submit">注册</button>
30       </mat-card-actions>
31     </mat-card>
32   </form>
33 </div>

register.component.ts

 1 import { Component,OnInit } from ‘@angular/core‘;
 2 import { FormGroup,FormBuilder } from ‘@angular/forms‘;
 3 
 4 @Component({
 5   selector: ‘app-register‘, 6   templateUrl: ‘./register.component.html‘, 7   styles: [`
 8   mat-form-field{width:100%;}
 9   form{
10     width: 500px;
11     margin: 20px auto;
12   }
13   `]
14 })
15 export class RegisterComponent implements OnInit {
16 
17   myGroup:FormGroup;
18   items=[];
19   constructor(private fb:FormBuilder) { }
20 
21   ngOnInit() {
22     const nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
23     this.items = nums.map(d=> `avatars:svg-${d}`);
24 
25     const img = `avatars:svg-${Math.floor(Math.random()*16).toFixed()}`;
26 
27     this.myGroup = this.fb.group({
28       email:[],29       username:[],30       password:[],31       repassword:[],32       avatar:[img]
33     });
34   }
35   onSubmit({value,valid},ev:Event){
36     console.log(value);
37     console.log(valid);
38   }
39 
40 }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读