让angular表单更简单
extend 组件的使用
公共的方法,属性
@Component({
selector: 'app-three',
templateUrl: './three.component.html',
})
export class ThreeComponent {
@Input() two = 'bbb';
@Input() three = 'ccc';
createMethod(val: any) {
console.log(val);
}
}
父组件继承, 跟html
没有关系
export class TwoComponent extends ThreeComponent implements OnInit {
@Input('one') one: string = 'aaa'
ngOnInit(): void {
}
}
html
<div>{{one}}</div>
<div>{{two}}</div>
<div>{{three}}</div>
<button (click)="createMethod('xxx')">CLICK</button>
我们可以把公共的方法和属性写成一个组件, 然后其他组件需要这部分继承
自定义指令扩展UI组件
@Directive({
// 组件
selector: 'p-calendar',
// 包含某个指令
selector: 'p-calendar[defaultCalendar]',
// 某个指令 排除某个指令
selector: 'p-calendar:not([resetCalendar])',
})
我们写个ng-zorro
的日期选择器
<nz-date-picker [(ngModel)]="date"
nzFormat="yyyy/MM/dd HH:mm:ss"
[nzShowTime]="false" [nzShowNow]="false"
[nzShowToday]="false" [nzAllowClear]="false" [nzBorderless]="true"></nz-date-picker>
我们发现上面的属性太多了,我们可以通过自定义指令执行处理
@Directive({
selector: 'nz-date-picker[appDateDefault]'
})
export class DateDefaultDirective {
constructor(private defaultDate: NzDatePickerComponent) {
this.defaultDate.nzBorderless = true;
this.defaultDate.nzAllowClear = false;
this.defaultDate.nzShowToday = false;
this.defaultDate.nzShowNow = false;
this.defaultDate.nzShowTime= false;
}
}
<nz-date-picker [(ngModel)]="date" nzFormat="yyyy/MM/dd HH:mm:ss" appDateDefault></nz-date-picker>
当我们需要对项目的90%以上添加这个指令, 可以设置排除某个属性
@Directive({
selector: 'nz-date-picker:not([appDateDefault])'
})
只要组件中不设置 appDateDefault 某符合, 类似于默认不写,也是符合要求的, 可用于修改组件的默认设置, 在这里基础上修复bug
指令修改子组件的表单
有时候我们纠结, 父组件修改子组件表单的信息, 我们看到常规来做,我们传入一个参数,然后做各种判断处理, 导致子组件的代码很累赘
子
@Component({
selector: 'person',
template: `
<div [formGroup]="form">
<div>
<label>Name</label>
<input type="text" formControlName="name" />
</div>
<div>
<label>Contact info</label>
<input type="text" formControlName="contactInfo" />
</div>
<div>
<label>Allergies</label>
<input type="text" formControlName="allergies" />
</div>
<strong>{{ form.valid ? 'valid' : 'invalid' }}</strong>
</div>
`,
})
export class PersonComponent {
form = this.formBuilder.group({
name: ['', Validators.required],
contactInfo: [''],
allergies: [''],
})
constructor(private formBuilder: FormBuilder) {}
}
给父级添加一个指令
@Directive({
selector: 'person[stage-one]',
})
export class StageOneDirective {
constructor(host: PersonComponent) {
host.form.get('contactInfo').setValidators([Validators.required])
}
}
添加另一个添加
@Directive({
selector: 'person[stage-one]',
})
export class StageOneDirective {
constructor(host: PersonComponent) {
host.form.get('contactInfo').setValidators([Validators.required])
}
}
然后使用的时候
<person></person>
<person stage-one></person>
<person stage-two></person>
自定义指令校验让Form表单更简单
校验器
import {Directive, Input} from '@angular/core';
import {AbstractControl, NG_VALIDATORS, ValidationErrors} from "@angular/forms";
@Directive({
selector: '[appValidator]',
providers: [{provide: NG_VALIDATORS, useExisting: ValidatorDirective, multi: true}],
})
export class ValidatorDirective {
@Input() appValidator!: (control: AbstractControl) => ValidationErrors | null;
validate(control: AbstractControl): ValidationErrors | null {
return this.appValidator(control);
}
}
组件
<input type="text" [appValidator]="scoreValidator" [(ngModel)]="date" #score="ngModel"/>
<app-has-error [control]="score.control"></app-has-error>
export class TwoComponent implements OnInit {
date = null
scoreValidator = (control: AbstractControl): ValidationErrors | null => {
const {dirty, touched, value} = control;
// 这个是为了默认默认的时候触发
if ((!!dirty || !!touched) && !value) {
return {required: true}
}
if (value?.length > 10) {
return {maxScore: 10};
}
return null;
};
}
app-has-error
@Input() control!: AbstractControl
这样我就可以做一些报错处理
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬