【问题标题】:Changing mat autocomplete values based on checkbox根据复选框更改垫子自动完成值
【发布时间】:2019-08-15 04:38:34
【问题描述】:

根据复选框是否被选中,垫子自动完成的值需要更改。当复选框未选中时,自动完成应显示活动程序。当复选框被选中时,自动完成应该显示非活动程序。

我看到的问题的步骤是:

    1) 不选中复选框
    2) 开始输入字母以查看活动程序
    3) 退格所有输入的字母
    4) 勾选复选框
    5)开始输入字母,我仍然看到活动程序列表,而我应该看到非活动程序

就好像我在选中或取消选中该框后需要将filteredOptions列表设置为一个空列表一样。

代码如下:

programs.component.html:

<form>
  <mat-form-field>
    <input type="text" placeholder="ProgramName" aria-label="ProgramName"
      matInput [formControl]="programNamesControl" [matAutocomplete]="auto" size="14" >
      <mat-autocomplete #auto="matAutocomplete" (optionSelected)='getSelectedProgram($event.option.value)' >
        <mat-option *ngFor="let option of filteredOptions | async" [value]="option" width:100px>
          {{option}}
        </mat-option>
      </mat-autocomplete>
  </mat-form-field>&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="checkbox" (change)="showInactivePrograms()" [(ngModel)]="programChecked" name="programChecked">
  <br/>
  <app-program-detail [programNameSelected]="programNameSelected" *ngIf="loadProgramDetails"></app-program-detail>
</form>

programs.component.ts

import { ProgramService } from './../program.service';
import { Component, OnInit, Input } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { Program } from '../program';

@Component({
  selector: 'app-programs',
  templateUrl: './programs.component.html',
  styleUrls: ['./programs.component.css']
})
export class ProgramsComponent implements OnInit {
  programNamesControl = new FormControl();
  programNames: string[] = [];
  filteredOptions: Observable<string[]>;
  programNameSelected: string;
  loadProgramDetails: boolean;
  programs: Program[] = [];
  programChecked: boolean;

  constructor(private programService: ProgramService) {

  }

  ngOnInit() {
    this.programService.getActiveProgramNames().subscribe(data => {
      this.programNames = data;
    });

    this.filteredOptions = this.programNamesControl.valueChanges.pipe(
      startWith(''),
      map(value => this._filter(value))
    );
  }

  _filter(value: string): string[] {
    console.log('Inside filter..');
    return this.programNames.filter(programName =>
      programName.toLowerCase().includes(value.toLowerCase())
    );
  }

  getSelectedProgram(programNameVal) {
    this.loadProgramDetails = true;
    this.programNameSelected = programNameVal;
    console.log('Program Selected is: ' + this.programNameSelected);
  }

  showInactivePrograms() {
    if (this.programChecked) {
      this.programService.getInActiveProgramNames().subscribe(data => {
        this.programNames = data;
      });
    }
    else {
      this.programService.getActiveProgramNames().subscribe(data => {
        this.programNames = data;
      });
    }
  }
}

program.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { Program } from './program';

@Injectable({
  providedIn: 'root'
})
export class ProgramService {

  constructor(private httpClient: HttpClient) { }

  getPrograms(): Observable<Program[]> {
    return this.httpClient.get<Program[]>(environment.apiBaseURL + 'api/Program')
                   .pipe(
                     map(data => data)
                   );
  }

  getActiveProgramNames(): Observable<string[]> {
    return this.getPrograms()
               .pipe(
                 map(data => data.filter(program => program.IsActive === 'Y'))
               )
               .pipe(
                 map(data => data.map(program => program.ProgramName.toString()))
               );
  }

  getInActiveProgramNames(): Observable<string[]> {
    return this.getPrograms()
               .pipe(
                 map(data => data.filter(program => program.IsActive === 'N'))
               )
               .pipe(
                 map(data => data.map(program => program.ProgramName.toString()))
               );
  }


  getProgram(programName: string): Observable<Program> {
    return this.httpClient.get<Program>(environment.apiBaseURL + 'api/Program?programName=' + programName)
              .pipe(
                map(data => data)
              );
  }

}

【问题讨论】:

  • 在 Stackblitz 上发布相关代码的工作版本,以便人们清楚地看到问题。
  • 如果可能,请为该问题创建一个 stackblitz 演示。

标签: angular angular-material angular6


【解决方案1】:

您需要在以下方法中切换 CheckBox 状态后立即重置数组“programNames”。因为 .subscribe() 或其他回调方法本质上是异步的。当您切换 CheckBox 直到 subscribe 事件被触发时,这些异步方法不会立即生效。

showInactivePrograms() {
    this.programNames = [];
    if (this.programChecked) {
        this.programService.getInActiveProgramNames().subscribe(data => {
        this.programNames = data;
    });
    }
    else {
        this.programService.getActiveProgramNames().subscribe(data => {
            this.programNames = data;
        });
    }
}

希望它能帮助您解决问题!

【讨论】:

    猜你喜欢
    • 2018-08-19
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 2020-05-10
    • 2015-11-27
    • 2019-10-06
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多