亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Angular ng-content 不適用于 mat-form-field

Angular ng-content 不適用于 mat-form-field

大話西游666 2023-03-03 13:34:36
我的目標:我正在嘗試構建一個帶有清除按鈕的可重復使用的 mat-form-field。我如何嘗試實現我的目標:我創建了一個“mat-clearable-input”組件并像這樣使用它:<mat-clearable-input>        <mat-label>Put a Number here pls</mat-label>        <input matInput formControlName="number_form_control">    </mat-clearable-input>mat-clearable-input.component.html<mat-form-field>    <ng-content></ng-content></mat-form-field>預期結果:ng-content 標簽獲取標簽和輸入并將它們放入 mat-form-field 標簽中。實際結果:Error: mat-form-field must contain a MatFormFieldControl.    at getMatFormFieldMissingControlError (form-field.js:226)    at MatFormField._validateControlChild (form-field.js:688)    at MatFormField.ngAfterContentChecked (form-field.js:558)    at callHook (core.js:2926)    at callHooks (core.js:2892)    at executeInitAndCheckHooks (core.js:2844)    at refreshView (core.js:7239)    at refreshComponent (core.js:8335)    at refreshChildComponents (core.js:6991)    at refreshView (core.js:7248)看起來我遺漏了一些東西而且我沒有正確使用 ng-content 標簽。我無法在 angular 網站上找到 ng-content 標簽的文檔。感謝您的任何幫助。在下面回答后編輯所以我嘗試了這個建議的方法:export class MatClearableInputComponent implements OnInit {  @ContentChild(MatFormFieldControl) _control: MatFormFieldControl<any>;  @ViewChild(MatFormField) _matFormField: MatFormField;  // see https://stackoverflow.com/questions/63898533/angular-ng-content-not-working-with-mat-form-field/  ngOnInit() {    this._matFormField._control = this._control;  }}不幸的是,當我嘗試在表單中使用它時,它仍然失敗并出現錯誤“錯誤:mat-form-field 必須包含 MatFormFieldControl”。我嘗試以某種形式使用此組件的代碼:<mat-clearable-input>    <mat-label>Numero incarico</mat-label>    <buffered-input matInput formControlName="numero"></buffered-input></mat-clearable-input>在 stackblitz 上重現:https://stackblitz.com/edit/angular-material-starter-xypjc5 ?file=app/clearable-form-field/clearable-form-field.component.html請注意 mat-form-field 功能如何不起作用(沒有輪廓,沒有浮動標簽),同時打開控制臺,您將看到錯誤錯誤:mat-form-field 必須包含 MatFormFieldControl。選項 2 發布后編輯我試過這樣做:<mat-form-field>  <input matInput hidden>  <ng-content></ng-content></mat-form-field>它有效,但是當我在我的表單字段中添加一個 mat-label 時,如下所示:      
查看完整描述

3 回答

?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

另一種解決方案是使用指令來實現行為。


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();

    }

  }

}

這會appClearable為后備布局創建一個名為的指令和一個可選的組件。確保將組件和指令添加到declarations模塊的 -array 中。您可以指定用于提供用戶界面的模板,也可以將其ClearButtonComponent用作通用的解決方案。標記如下所示:


<!-- 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>

無論是否使用 ngControl/FormControl,這都適用,但您可能需要根據您的用例對其進行調整。


查看完整回答
反對 回復 2023-03-03
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

從 2022 年的 Angular 14 開始,MatFormField 的問題已經針對angular/angular#37319關閉,沒有解決方案。如果您需要它工作,以下似乎是現在可以使用<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);

  }

}


查看完整回答
反對 回復 2023-03-03
?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

更新:


選項 1 不適用于新的角度版本,因為在鉤子@ViewChild()中返回未定義。ngOnInit()另一個技巧是使用假人MatFormFieldControl-


選項 2


<mat-form-field>

  <input matInput hidden>

  <ng-content></ng-content>

</mat-form-field>

編輯:


拋出該錯誤是因為MatFormField組件查詢使用的子內容@ContentChild(MatFormFieldControl)如果您使用嵌套則不起作用ng-content(MatFormField 也使用內容投影)。


選項 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;

    }

}

請檢查這個 stackBlitz。此外,已經創建了這個問題github



查看完整回答
反對 回復 2023-03-03
  • 3 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號