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
這樣我就可以做一些報錯處理