0

我创建了一个 stackBliz,它是我想要实现的一个较小的示例,但如果我可以让它在那里工作的话。然后,我应该能够弄清楚其余的。

https://stackblitz.com/edit/angular-nkajg5

当用户输入的输入不是垫自动完成中建议项目中的项目时,我想清除或将组件的值设置为“”。然后,我还想向他们显示一个垫子错误,即“输入的值无效,请仅从建议的值中选择。”

我通过以下两个我找到的例子让它工作。清除输入

https://stackblitz.com/edit/autocomplete-force-selection-tests-w2fqww?file=app%2Fapp.component.html

告诉他们错误信息

https://stackblitz.com/edit/angular-kdym4u

但是,我有三个自动完成组件,当我尝试在所有三个组件上使用该方法并从 ngAfterViewInit 调用它们时,它会导致问题。没有错误消息它只是不清除输入或显示错误消息。所以我的函数似乎没有被调用。(老实说,我不确定订阅变量在代码中的用途)我认为它必须与订阅以及我从 ngAfterViewInt() 调用它的位置有关。我对其进行了测试,只有第一个组件本身可以工作。我自己也尝试了其他两个组件,即使它们是唯一使用的控件,它们也根本不起作用。我在 tabGroup 中有三个 matAutocomplete,另外两个在 tabGroup 的第二个选项卡中。

我的构造函数和我的表单组

  constructor(private dialogRecipient:MatDialog,private fb: FormBuilder, private dialogRef: MatDialogRef<UpdateTaskComponent>,private snackBar: MatSnackBar, 
    @Inject(MAT_DIALOG_DATA){Enabled ,TaskName, TaskDescription,EmailSubject, EmailBody, tTaskTeam, PK_Task}, private service: TaskService ) { 
      this.pk_Task = PK_Task;
      console.log(this.pk_Task)
      this.form = fb.group({
        enabled: [Enabled],
        tTaskTeam: [tTaskTeam, Validators.required],
        taskName: [TaskName],
        taskDescription: [TaskDescription],
        emailSubject: [EmailSubject],
        emailBody: [EmailBody]
      })

      this.AdditionalRecipientForm = fb.group({
        recipientType: ['',Validators.required],
        tofficeUser: ['',Validators.required],
        tOfficeUserEmail: '',
        FK_Task: [this.pk_Task]
      })

    }

我如何使用@ViewChild 来获取 MatAutoCompletes

  @ViewChild(MatAutocomplete) autoCompleteForTaskTeam: MatAutocomplete;
  @ViewChild('auto') auto: MatAutocomplete;
  @ViewChild('autotest') autotest: MatAutocomplete;
  @ViewChild(MatTable) table: MatTable<RecipientInterface>;
  @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
  subscription: Subscription;

我在哪里调用控件上的方法

ngAfterViewInit() {

如果我只调用 tTaskTeam 控件它可以工作,但是当我把所有三个它都停止工作

this._subscribeToClosingActions(this.form.controls.tTaskTeam); 
this._subscribeToClosingActions(this.AdditionalRecipientForm.controls.recipientType);
    this._subscribeToClosingActions(this.AdditionalRecipientForm.controls.tofficeUser);
        }

ngOnDestroy() {
  if (this.subscription && !this.subscription.closed) {
    this.subscription.unsubscribe();
  }
}

显示错误的方法,将我的控件设置为“”,如果它不是建议的值,则清除它。

private _subscribeToClosingActions(control): void {
  if (this.subscription && !this.subscription.closed) {
    this.subscription.unsubscribe();
  }
  this.subscription = this.trigger.panelClosingActions
    .subscribe(e => {
      if (!e || !e.source) {
       control.setValue('');
      }
    },
    err => this._subscribeToClosingActions(control),
    () => this._subscribeToClosingActions(control));
}

模板代码:

<h2 mat-dialog-title>Update Entry</h2>
<mat-tab-group dynamicHeight>
  <mat-tab label="Task Information">
    <div class="example-small-box mat-elevation-z4">
      <mat-dialog-content  [formGroup]="form" class="example-form" >
        <mat-slide-toggle color="primary" (click)="textForToggle()" formControlName="enabled" >{{toggle ? 'Enabled': 'Disabled'}}</mat-slide-toggle>

            <mat-form-field class="task-info-form-field" >
                <input matInput placeholder="Report Name" formControlName="taskName">
            </mat-form-field>
            <br>
            <mat-form-field  appearance="outline" class="task-info-form-field" >

第一个自动完成组件

<input matInput (keyup.enter)="chooseFirstOption(autoCompleteForTaskTeam)" [matAutocomplete]="autoCompleteForTaskTeam" formControlName="tTaskTeam" matTooltip="You can search and it will try to autocomplete the name for you!" placeholder="Select Group">
                  <mat-autocomplete #autoCompleteForTaskTeam='matAutocomplete'  [displayWith]="displayTeamName">
                    <mat-option class="matAutoCompleteSelect"*ngFor="let user of filteredOptions | async" 
                      [value]="user">
                      <span>{{ user.TeamName }}</span>
                    </mat-option>
                  </mat-autocomplete>
                  <mat-error >
                    Value entered is NOT VALID please selected only from suggested values.
                  </mat-error>
                </mat-form-field>
                <br>
                <mat-form-field class="task-info-form-field" >
                  <textarea #message matInput placeholder="Report Description"  formControlName="taskDescription"></textarea>
                  <mat-hint align="end">{{message.value.length}} / 256</mat-hint>
                  <mat-hint align="start"><strong>Put a detailed Description</strong> </mat-hint>
                  <mat-error >
                    Please enter less than 256 characters.
                  </mat-error>
                </mat-form-field>
                <br>
                <mat-form-field class="task-info-form-field" >
                  <input matInput placeholder="Email Subject: " formControlName="emailSubject">
                </mat-form-field>
                <br>
                <mat-form-field class="task-info-form-field">
                  <textarea matInput #message2 placeholder="Email Body"  formControlName="emailBody"></textarea>
                  <mat-hint align="end">{{message2.value.length}} / 256</mat-hint>
                  <mat-error >
                    Please enter less than 256 characters.
                  </mat-error>
                </mat-form-field>
          </mat-dialog-content>

        </div>
      </mat-tab>
      <mat-tab class="example-containerGrid" label="Recipient Information">

        <div class="example-containerGrid mat-elevation-z8">
          <div class="example-header">
            <mat-form-field class="searchGrid-form-field">
              <input matInput #filter (keyup)="applyFilter($event.target.value)" placeholder="Filter Doesn't Work At The Moment">
              <button mat-icon-button matSuffix aria-label="clear" *ngIf="filter.value" (click)="filter.value=''; applyFilter('');">
                <mat-icon>close</mat-icon>
              </button>
            </mat-form-field>
          </div>

          <mat-table #table [dataSource]="dataSource">

            <ng-container matColumnDef="Login">
              <mat-header-cell *matHeaderCellDef> Login </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element.tOfficeUser.Login}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="Email">
              <mat-header-cell class="actionsCell" *matHeaderCellDef> Email </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element.tOfficeUser.Email}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="typerecipient">
              <mat-header-cell *matHeaderCellDef> Type Of Recipient </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element.RecipientType.typerecipient}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="Actions">
                <mat-header-cell  *matHeaderCellDef> Actions  </mat-header-cell>
                <mat-cell  *matCellDef="let element"> {{element.Actions}}
                <div class="example-button-row">  
                  <button mat-raised-button color="primary"  (click)="updateRecipientInfo(element)"> <mat-icon class="example-icon" matTooltip="You can edit this report">edit</mat-icon> <b>Edit</b></button>
                  <!-- <button mat-raised-button (click)="test">  <mat-icon class="example-icon" matTooltip="This button is to copy reports"> filter_none </mat-icon><b>Copy</b></button> -->
                  <button mat-raised-button color="warn" (click)="deleteRecipient(element)">  <mat-icon class="example-icon" matTooltip="This is to delete this report"> delete_outline</mat-icon><b>Delete</b></button>
                </div>
              </mat-cell>
            </ng-container>

            <!-- Fav Column -->
            <!-- <ng-container matColumnDef="fav">
              <mat-header-cell *matHeaderCellDef> Favorite </mat-header-cell>
              <mat-cell *matCellDef="let element">
                <mat-form-field floatLabel="never">
                  <mat-select [(value)]="element.fav" placeholder="Favorite">
                    <mat-option>None</mat-option>
                    <mat-option value="Yes">Yes</mat-option>
                  </mat-select>
                </mat-form-field>
              </mat-cell>
            </ng-container> -->

            <mat-header-row *matHeaderRowDef="columnsToDisplay; sticky: true"></mat-header-row>
            <mat-row *matRowDef="let row; columns: columnsToDisplay;"></mat-row>
          </mat-table>
          <mat-card class="spinnerMatCard" *ngIf="isLoading">
              <mat-progress-spinner 
                color="primary" 
                mode="indeterminate">
              </mat-progress-spinner>
            </mat-card>
        </div>



        <div class="example-container mat-elevation-z8">
            <mat-accordion>
                <mat-expansion-panel [formGroup]="AdditionalRecipientForm"> 
                  <mat-expansion-panel-header [collapsedHeight]="customCollapsedHeight" [expandedHeight]="customExpandedHeight">
                    <mat-panel-title>
                      Add Additional Recipients
                    </mat-panel-title>
                    <mat-panel-description>
                      Type your name and age
                    </mat-panel-description>
                  </mat-expansion-panel-header>
                  <button mat-raised-button (click)="createNewRecipientUser()" [disabled]="!AdditionalRecipientForm.valid" [disabled]="!AdditionalRecipientForm.dirty" color="primary"><b>Update</b></button>
                  <button mat-raised-button  (click)="resetFields()" color="primary"><b>Reset</b></button>
                  <br>

                    <mat-form-field appearance="outline">
                        <mat-label>Login Name Field</mat-label>

第二个 autoComplete 组件

 matTooltip="You can search and it will try to autocomplete the name for you!" placeholder="Select Type Of Logins">

                <mat-hint>You can type in the name and it will autocomplete for you!</mat-hint>
              <mat-autocomplete #auto [displayWith]="displayLogin">
                  <mat-option class="matAutoCompleteSelect"*ngFor="let user of OfficeUserfilteredOptions | async" 
                    [value]="user">
                    <span>{{ user.Login }}</span>
                  </mat-option>
              </mat-autocomplete>
              <mat-error >
                Value entered is NOT VALID please selected only from suggested values.
              </mat-error>
            </mat-form-field>

            <mat-form-field class="add-addtional-recipients-form-field" appearance="outline">
                <mat-label>Email Field</mat-label>
              <input  matInput placeholder="User Email Address"   formControlName="tOfficeUserEmail">

              <mat-hint align="left"><strong>You cannot edit user email address here! Select a login to see the email.</strong> </mat-hint>
            </mat-form-field>

            <mat-form-field class="add-addtional-recipients-form-field" appearance="outline">
                <mat-label>Recipient Type</mat-label>

第三个 autoComplete 组件

   <input matInput [matAutocomplete]="autotest" (keyup.enter)="chooseFirstOptionForAutoTest()" formControlName="recipientType" matTooltip="You can search and it will try to autocomplete the name for you!" placeholder="Select Type Of Recipient">
                <mat-hint>Start typing in the type of reicpient you want. </mat-hint>
                <mat-autocomplete #autotest  [displayWith]="displayRecipientName">
                  <mat-option class="matAutoCompleteSelect"*ngFor="let user of filteredRecipientOptions | async" 
                    [value]="user">
                    <span>{{ user.typerecipient }}</span>
                  </mat-option>
                </mat-autocomplete>
                <mat-error >
                  Value entered is NOT VALID please selected only from suggested values.
                </mat-error>
              </mat-form-field>
        </mat-expansion-panel>
      </mat-accordion>
</div> 

关闭 保存

4

1 回答 1

0

如果有人开始在表单中使用多个自动完成功能,并且想要清除输入(如果它不是您的数据中建议的项目之一)并显示错误消息。我找到了一个解决方案:

我的问题是我试图引用的触发器只找到它在 DOM 中找到的第一个自动完成功能。

 @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;

所以,我需要订阅每个 MatAutoComplete 触发器,因为它们每个都有自己的触发器。为了能够做到这一点,我们必须创建一个

@ViewChildren(MatAutocompleteTrigger) triggerCollection: QueryList<MatAutocompleteTrigger>;

这将保存所有 matAutComplete 控件触发器的集合。

从那里我们可以通过将其设为数组并检查哪些控件是脏的来遍历集合。

private _subscribeToClosingActions(): void {

    if (this.subscription && !this.subscription.closed) {
      this.subscription.unsubscribe();
    }

for (var trigger of this.triggerCollection.toArray()) {
    this.subscription = trigger.panelClosingActions
      .subscribe(e => {
        if (!e || !e.source) {
        if(this.CarsFormGroup.controls.carCtrl.dirty) {
 this.CarsFormGroup.controls.carCtrl.setValue(null);
          }
        if(this.StatesFormGroup.controls.stateCtrl.dirty) {
 this.StatesFormGroup.controls.stateCtrl.setValue(null);
          }
        }
  });
}
  }
于 2019-05-29T15:46:49.150 回答