【问题标题】:Angular Material autocomplete validate only the options on the listAngular Material 自动完成功能仅验证列表中的选项
【发布时间】:2020-10-25 11:57:51
【问题描述】:

我有一个 Angular 应用程序,我想在我的应用程序中实现自动完成下拉菜单, 我检查了 Angular 材料中的示例代码,它并不完美,即使用户选择了一个选项,它也允许用户输入。它不验证。 我想要这样的东西(https://bootsnipp.com/snippets/0Bn1j) 我的选项应该是 Key Value,Key 应该是 CountryID,Value 应该是 CountryName 我是新手,任何帮助将不胜感激。 我在这里看到了一个例子 (https://stackblitz.com/edit/angular-autocomplete-validation?file=src%2Fapp%2Fautocomplete-validation-example.html) 但它的选项是字符串 我的选项来自带有 CountryId 和 CountryName 的数据库表

component.ts:


     function autocompleteStringValidator(validOptions: Array<string>):   ValidatorFn {
    console.log(validOptions);
    return (control: AbstractControl): { [key: string]: any } | null => {
    if (validOptions.indexOf(control.value) !== -1) {
      return null  /* valid option selected */
    }
    return { 'invalidAutocompleteString': { value: control.value } }
    }
    }

    
     
    export class TasksformComponent implements OnInit {

     
     public phoneLabelOptions: any[] = [];
     public filteredPhoneLabelOptions: Observable<any[]>
     public phoneLabelAutocompleteControl = new FormControl('', 
      { validators: [autocompleteStringValidator(this.phoneLabelOptions), Validators.required] })

      public validation_msgs = {
        'contactAutocompleteControl': [
          { type: 'invalidAutocompleteObject', message: 'Contact name not recognized. Click one of the autocomplete options.' },
          { type: 'required', message: 'Contact is required.' }
        ],
        'phoneLabelAutocompleteControl': [
          { type: 'invalidAutocompleteString', message: 'Phone label not recognized. Click one of the autocomplete options.' },
          { type: 'required', message: 'Phone label is required.' }
        ]
      }

        private _filterPhoneLabels(label: any): any[] {
      console.log('---cling----');
      console.log(label);
      if (label === '') {
        return this.phoneLabelOptions.slice()
      }
      const filterValue = label.toLowerCase()
      return this.phoneLabelOptions.filter(option => option.Name.toLowerCase().includes(filterValue))
     }

      ngOnInit(): void{
       
         this.filteredPhoneLabelOptions = this.phoneLabelAutocompleteControl.valueChanges.pipe(
      startWith(''),
      map((value) => {
        console.log('---ite here----');
        console.log(value);
        return this._filterPhoneLabels(value)
      })
     )
       
      let lookupTablename: string;
      console.log('------'+this.categoryID);
      this.selected = this.categoryID;
      this.lookupService.getLookupByTableAlias((lookupTablename = 'category')).subscribe(
      (icategory: any) => {
        this.category = icategory;
        //console.log(icategory);
        icategory.forEach((item)=>{
          this.phoneLabelOptions.push({ID:item.ID, Name:item.Name});
        });
        console.log(this.phoneLabelOptions);
      },
      error => {
        const res = this.dialogService.ErrorDialog('Server Error', 'Sorry, the system is unavailable at the moment.', 'Close', 'Try Again');
        res.afterClosed().subscribe(dialogResult => {
          if (dialogResult) {
            this.callNext(4000);
          }
        });
        }
      );
     }

component.html:


            <mat-form-field>
                        <input type="text" placeholder="Phone label" aria-label="Phone label" matInput 
                        [formControl]="phoneLabelAutocompleteControl" [matAutocomplete]="autoPhoneLabel">
                        <mat-autocomplete #autoPhoneLabel="matAutocomplete">
                          <mat-option *ngFor="let label of filteredPhoneLabelOptions | async" [value]="label.ID">
                            {{label.Name}}
                          </mat-option>
                        </mat-autocomplete>
                
                        <mat-error *ngFor="let validation of validation_msgs.phoneLabelAutocompleteControl">
                          <div *ngIf="phoneLabelAutocompleteControl.hasError(validation.type)">
                            {{validation.message}}
                          </div>
                        </mat-error>
                      </mat-form-field>

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    我相信你可以使用 mat-auto-complete。

    https://stackblitz.com/edit/angular-autocomplete-validation?file=src%2Fapp%2Fautocomplete-validation-example.html)

    您所要做的就是同时提供数组中的值。

      public contactOptions: Contact[] = [
        {id: 1, name: 'Elton John', value:'elton'},
        {id: 2, name: 'Elvis Presley', value:'Elvis'},
        {id: 3, name: 'Paul McCartney', value:'Paul'}
      ]
    

    并且该值可以从界面设置为字符串或数字。

    export interface Contact {
      name: string;
      value:string;
      id: number;
    }
    

    好的,现在我们已经完成了一半。选择下拉值后,您将能够获取名称。使用该名称,您只需在 contactOptions 数组中添加 find() 方法并获取尊重的值即可。

    let result:any = this.contactOptions.find(res=> res.name === selectedValue); 
    let value = result.value; //===> value: '' from object
    let id = result.id
    

    【讨论】:

    • 我获取了 op 提供的链接。
    • 如果您使用的是文本版本,也可以内联解释代码。
    • 如果你可以在我的代码中看到我需要的值是 ID,它是数字而不是字符串
    • 你想成为哪个值的 ID ?你说的是界面吗?
    • 是的,一旦我选择了 ID 值,这些过滤函数首先会按字符串检查,它会导致转换为小写时出错,并且数字会显示在下拉列表中
    猜你喜欢
    • 2019-01-23
    • 2015-12-29
    • 2015-08-22
    • 1970-01-01
    • 2016-03-23
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    相关资源
    最近更新 更多