首页 > 解决方案 > Angular 在每个选择更改事件上加载新的自动完成值

问题描述

我的表单中有几个最重要的字段。在第一种形式中,用户应该通过 mat-select-search 选择公司。之后,通过使用 (selectionChange),我在第一个字段(这是公司 ID)中使用选定的值调用 API,并返回该公司的用户以自动完成收件人字段。如果用户不更改他选择的公司,它会完美运行。但是,如果他这样做 (selectionChange) 方法不会重新加载具有新值的自动完成功能。在这种情况下,用户选择了另一家公司,而自动完成功能仍然保留在前一个公司中。如果先前的输出为空,事件只会加载新的。是否有可能改变这种行为?是否可以从 api 调用中删除以前的结果?

我的表格:

  <form [formGroup]="orderForm" novalidate (ngSubmit)="createOrder()">

                              <div class="row">
                                <div class="col-md-12">
                                  <mat-form-field class="example-full-width"  formGroupName='Company'>
                                    <mat-select ngDefaultControl  placeholder="Company" #singleSelect formControlName="id" (openedChange)="onSelectionChange($event)" [(value)]="selectedVariable">
                                    <mat-option>
                                      <ngx-mat-select-search [formControl]="companySelectFilter"  [searching]="searching" placeholderLabel="Find company..." noEntriesFoundLabel="'no matching companies found'" ></ngx-mat-select-search>
                                    </mat-option>
                                      <mat-option *ngFor="let company of filteredCompanies | async" [value]="company.id">
                                        {{company.company_name| titlecase}} {{company.company_address| titlecase}}
                                      </mat-option>
                                    </mat-select>
                                  <mat-error *ngIf="orderForm.hasError('notSame')">
                                    Recipient has another company! Select again.
                                  </mat-error>
                                  </mat-form-field>
                                </div>
                              </div>
<div class="row" matAutocompleteOrigin #origin="matAutocompleteOrigin">
                              <div class="col-md-6">

                                <mat-form-field class="example-full-width" formGroupName='recipient' >

                                  <input type="text"
                                   matInput  
                                    formControlName="user_name" 
                                    placeholder="First Name" 
                                    [matAutocomplete]="auto" 
                                     [matAutocompleteConnectedTo]="origin">
                                  <mat-autocomplete #auto="matAutocomplete" (optionSelected)="setFormData($event)">
                                    <mat-option *ngFor="let recipient of filteredOptions | async" [value]="recipient">
                                      <div style="display:flex;flex-wrap: nowrap;align-items:center;justify-content:center;margin: auto;">
                                        <span style="flex-grow: 1;flex: 1 1 33%;"> {{recipient.user_name.toString() | titlecase}} {{recipient.user_surname.toString() | titlecase}} {{recipient.company.company_name.toString() | titlecase}}
                                          </span>
                                      </div>
                                    </mat-option>
                                  </mat-autocomplete>



                                 </mat-form-field>
                              </div>

                              <div class="col-md-6" >
                                <mat-form-field class="example-full-width" formGroupName='recipient'>
                                  <input matInput formControlName="user_surname"   placeholder="Last Name"[matAutocomplete]="auto"
                                          [matAutocompleteConnectedTo]="origin" >
                                          <mat-error *ngIf="orderForm.get('recipient.user_surname').hasError('required')">
                                            Last Name is <strong>required</strong>

                                          </mat-error>
                                </mat-form-field>
                              </div>
                          </div>
                          <div class="col-md-6" >
                            <mat-form-field class="example-full-width" formGroupName='recipient'>
                              <input matInput placeholder="Mobile Phone" type="text" formControlName="user_telephone" >
                            </mat-form-field>
                          </div>

OnSelected 更改方法:

  onSelectionChange(opened: boolean) {
    console.log(`opened is : ${opened}`);
    if (!opened && this.selectedVariable) {

      this.orderForm.get('recipient.user_name').reset()
      this.orderForm.get('recipient.user_surname').reset()
      this.orderForm.get('recipient.user_telephone').reset()

      this.filteredOptions = this.orderForm
        .get('recipient.user_name')
      .valueChanges.pipe(
        startWith(""),
        debounceTime(400),
        distinctUntilChanged(),
        switchMap((val) => {
          return this.doFilter(this.selectedVariable, val || '');
        })
      );
          }
  } 

和 doFilter 方法:

doFilter(id: number, val: any): Observable<any[]> {
    return this.recipientService.getRecipientsByCompany(id).pipe(
      map((response) =>
        response.filter((option) => {
          return (
            option.user_name
              .toString()
              .toLowerCase()
              .indexOf(val.toString().toLowerCase()) === 0 ||
            option.user_surname
              .toString()
              .toLowerCase()
              .indexOf(val.toString().toLowerCase()) === 0
          );
        })
      )
    );
  }

标签: htmlangulartypescriptautocompleteangular-material

解决方案


最后,我找到了解决方案。我的错误是我试图在页面加载后从 API 检索数据。现在,我在 NgOnInit 方法中加载所有收件人,并在用户更改公司后过滤数据。

我们放入 ngOnInit 的 LoadRecipients 方法:

    this.recipientService
      .getRecipientsObs()
      .subscribe((recipients) => (this.recipients = recipients));
  }

和新的 OnChange 方法:

selectedVariable: any;
  onSelectionChange(opened: boolean) {
    console.log(`opened is : ${opened}`);
    console.log(this.selectedVariable)
    if (!opened && this.selectedVariable) {
      this.orderForm.get("recipient.user_name").reset();
      this.orderForm.get("recipient.user_surname").reset();
      this.orderForm.get("recipient.user_telephone").reset();
      const formsInput = merge(
        this.orderForm.get('recipient.user_name').valueChanges,
        this.orderForm.get('recipient.user_surname').valueChanges
      );
     formsInput.pipe(
        startWith(""),
        debounceTime(400),
        distinctUntilChanged(),
        map((search) => {
          if (!this.recipients) {
            return [];
          } else {
            search = search.toLowerCase();
          }

          return this.recipients.filter(
            (recipient) =>
              recipient.company.id === this.selectedVariable &&
              recipient.user_name.toLowerCase().indexOf(search) > -1 &&
              recipient.user_surname.toLowerCase().indexOf(search) > -1 
          );
        }),
        delay(500)
      )
      .subscribe(
        (filteredRecipients) => {
          this.searching = false;
          this.filteredRecipients.next(filteredRecipients);
        },
        (error) => {
          this.searching = false;
        }
      );
    }
  }

推荐阅读