1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > angular 响应式自定义表单控件—注册头像实例

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

时间:2023-03-05 01:22:54

相关推荐

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

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,useExisting:forwardRef(()=>ImageListSelectComponent),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-ponent.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-ponent.html', 7 styles: [], 8 providers:[ 9{10 provide:NG_VALUE_ACCESSOR,11 useExisting:forwardRef(()=>ImageListSelectComponent),12 multi:true13},14{15 provide:NG_VALIDATORS,16 useExisting:forwardRef(()=>ImageListSelectComponent),17 multi:true18}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{34console.log(obj);35this.selectedImg = obj;36 }37 registerOnChange(fn: (_: any) => void): void {38this._onChange = fn;39 }40 41 registerOnTouched(fn: any): void {42 }43 44 validate(c:FormControl):{[key:string]:any}{45return this.selectedImg ? null :{46 imageListNotValid:true47}48 }49 50 changeSelected(index){51this.selectedImg = this.items[index];52this._onChange(this.selectedImg);53 }54 55 }

app-image-list-ponent.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>

ponent.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-select20 [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>

ponent.ts

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。