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 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |