3 回答

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超3個(gè)贊
另一種解決方案是使用指令來(lái)實(shí)現(xiàn)行為。
import {
AfterViewInit,
Component,
ComponentFactory,
ComponentFactoryResolver,
ContentChild,
Directive,
Injector,
Input,
Optional,
SkipSelf,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { MatFormFieldControl } from '@angular/material/form-field';
@Directive({
selector: '[appClearable]'
})
export class ClearableDirective implements AfterViewInit {
@ContentChild(MatFormFieldControl) matInput: MatFormFieldControl<any>;
@Input() appClearable: TemplateRef<any>;
private factory: ComponentFactory<ClearButtonComponent>;
constructor(
private vcr: ViewContainerRef,
resolver: ComponentFactoryResolver,
private injector: Injector,
) {
this.factory = resolver.resolveComponentFactory(ClearButtonComponent);
}
ngAfterViewInit(): void {
if (this.appClearable) {
this.vcr.createEmbeddedView(this.appClearable);
} else {
this.vcr.createComponent(this.factory, undefined, this.injector);
}
}
/**
* This is used to clear the formControl oder HTMLInputElement
*/
clear(): void {
if (this.matInput.ngControl) {
this.matInput.ngControl.control.reset();
} else {
this.matInput.value = '';
}
}
}
/**
* This is the markup/component for the clear-button that is shown to the user.
*/
@Component({
selector: 'app-clear-button',
template: `
<button (click)="clearHost()">Clear</button>
`
})
export class ClearButtonComponent {
constructor(@Optional() @SkipSelf() private clearDirective: ClearableDirective) { }
clearHost(): void {
if (this.clearDirective) {
this.clearDirective.clear();
}
}
}
這會(huì)appClearable為后備布局創(chuàng)建一個(gè)名為的指令和一個(gè)可選的組件。確保將組件和指令添加到declarations模塊的 -array 中。您可以指定用于提供用戶界面的模板,也可以將其ClearButtonComponent用作通用的解決方案。標(biāo)記如下所示:
<!-- Use it with a template reference -->
<mat-form-field [appClearable]="clearableTmpl">
<input type="text" matInput [formControl]="exampleInput">
</mat-form-field>
<!-- use it without a template reference -->
<mat-form-field appClearable>
<input type="text" matInput [formControl]="exampleInput2">
</mat-form-field>
<ng-template #clearableTmpl>
<button (click)="exampleInput.reset()">Marked-Up reference template</button>
</ng-template>
無(wú)論是否使用 ngControl/FormControl,這都適用,但您可能需要根據(jù)您的用例對(duì)其進(jìn)行調(diào)整。

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超13個(gè)贊
從 2022 年的 Angular 14 開始,MatFormField 的問(wèn)題已經(jīng)針對(duì)angular/angular#37319關(guān)閉,沒(méi)有解決方案。如果您需要它工作,以下似乎是現(xiàn)在可以使用<ng-content>
with的最佳解決方案mat-form-field
:
@Component({
selector: 'my-input-wrapper',
template: `
<mat-form-field appearance="standard">
<ng-content></ng-content>
<!-- make sure this is destroyed so all bindings/subscriptions are removed-->
<input *ngIf="isBeforeViewInit$$ | async" hidden matInput />
</mat-form-field>
`,
});
class MyInputWrapper implement AfterViewInit {
isBeforeViewInit$$ = new BehaviorSubject(true);
@ContentChild(MatFormFieldControl) matFormControl: MatFormFieldControl<unknown>;
@ViewChild(MatFormField) matFormField: MatFormField;
ngAfterViewInit() {
// replace the reference to the dummy control
this.matFormField._control = this.matFormControl;
// force the form field to rebind everything to the actual control
this.matFormField.ngAfterContentInit();
this.isBeforeViewInit$$.next(false);
}
}

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超9個(gè)贊
更新:
選項(xiàng) 1 不適用于新的角度版本,因?yàn)樵阢^子@ViewChild()中返回未定義。ngOnInit()另一個(gè)技巧是使用假人MatFormFieldControl-
選項(xiàng) 2
<mat-form-field>
<input matInput hidden>
<ng-content></ng-content>
</mat-form-field>
編輯:
拋出該錯(cuò)誤是因?yàn)镸atFormField組件查詢使用的子內(nèi)容@ContentChild(MatFormFieldControl)如果您使用嵌套則不起作用ng-content(MatFormField 也使用內(nèi)容投影)。
選項(xiàng) 1(已棄用)
以下是如何讓它工作 -
@Component({
selector: 'mat-clearable-input',
template: `
<mat-form-field>
<ng-content></ng-content>
</mat-form-field>
`
})
export class FieldComponent implements OnInit {
@ContentChild(MatFormFieldControl) _control: MatFormFieldControl<any>;
@ViewChild(MatFormField) _matFormField: MatFormField;
ngOnInit() {
this._matFormField._control = this._control;
}
}
請(qǐng)檢查這個(gè) stackBlitz。此外,已經(jīng)創(chuàng)建了這個(gè)問(wèn)題github
。
添加回答
舉報(bào)