Angular 5 / Material 2 - 选择选项后字段中的值错误

时间:2018-01-19 11:40:02

标签: mongodb angular typescript angular-material2

我的Angular Material 2 Autocomplete字段存在问题。

这是我的设置:

hardwareCreate.component.ts

myControl: FormControl = new FormControl();
availableFirmware = [];
filteredFirmware: Observable<any[]>;
selectedFirmware = null;
selectedFirmwareName = '';



this.availableFirmware = [];

    this.terminalService.getFirmware().subscribe(firmware => {
      this.availableFirmware = firmware.firmware;
    });
    this.filteredFirmware = this.myControl.valueChanges
    .pipe(
      startWith(''),
      map(val => this.filterFirmware(val))
    );

filterFirmware(val: any): any[] {
    return this.availableFirmware.filter(firmware => {
      return firmware.name.toLowerCase().indexOf(val.toLowerCase()) > -1;
    });
  }

hardwareCreate.component.html

<div class="form-group">
        <mat-form-field class="example-full-width">
            <input type="text" placeholder="Firmware auswählen" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto1" [(ngModel)]="selectedFirmwareName">
            <mat-autocomplete #auto1="matAutocomplete">
                <mat-option *ngFor="let firmware of filteredFirmware | async" [value]="firmware._id">
                    {{ firmware.name }}
                </mat-option>
            </mat-autocomplete>
        </mat-form-field>
    </div>

所以现在我的问题是,当我输入时,我得到的firmware.name属性是正确的,看起来像这样: enter image description here

但是,当我现在选择固件时,value会更改为_id的{​​{1}}。 enter image description here

所以我可以将firmware更改为[value]="firmware._id",但我需要我的mongodb的ID - &gt;

[value]="firmware.name"

问题: 如何将显示值更改为名称,但在用户选择特定固件时仍然可以获取我的数据库的ID?

现在的解决方案是vsoni和JEYs答案的组合。最后的问题是,firmware: { type: mongoose.Schema.Types.ObjectId, ref: 'Firmware' }, 是一个对象。通过将其转换为字符串,任何东西都像魅力一样! 谢谢你们两位!

2 个答案:

答案 0 :(得分:4)

您可以使用displayWith功能。

component.html 将成为

<div class="form-group">
    <mat-form-field class="example-full-width">
        <input type="text" placeholder="Firmware auswählen" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto1">
        <mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFn">
            <mat-option *ngFor="let firmware of filteredFirmware | async" [value]="firmware" (onSelectionChange)="getXXX(firmware)>
                {{ firmware.name }}
            </mat-option>
        </mat-autocomplete>
    </mat-form-field>
</div>

然后在 component.ts

中定义以下显示功能
displayFn(firmware: any): string {
  return firmware? firmware.name : firmware;
}

您可以访问 component.ts 中定义的getXXX(firmware)功能中的固件ID。选择更改时将调用此函数。

getXXX(firmware) {
   this.selectedFirmware = firmware;
   // here you can get id 
  // firmware._id
}

和过滤功能

filterFirmware(val: any): any[] {
    let name = val.name ? val.name : val;
    return this.availableFirmware.filter(firmware => {
      return firmware.name.toLowerCase().indexOf(name.toLowerCase()) > -1;
    });
  }

答案 1 :(得分:1)

您可以使用displayWith属性,例如:

在您的组件中:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { map } from 'rxjs/operators/map';
import {startWith} from 'rxjs/operators/startWith';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  implements OnInit, OnDestroy {

  myControl = new FormControl();
  availableFirmware = [{name: 'Firmware 1', id: 1}, {name: 'Firmware 2', id: 2}, {name: 'Firmware 3', id: 3}];
  selected = null;
  filteredFirmware: Observable<any>;
  subcribtion: Subscription;

  displayFirmware(firmware?: any) {
    return firmware ? firmware.name : undefined;
  }

  filterFirmware(val: any): any[] {
    return this.availableFirmware.filter(firmware => {
      // when no selection occured value is a string
      // but once a firmware is selected value is an object
      let name = val.name ? val.name : val;
      return firmware.name.toLowerCase().indexOf(name.toLowerCase()) === 0;
    });
  }

  ngOnInit() {
    this.subcribtion = this.myControl.valueChanges.subscribe(value => this.selected = value);
    this.filteredFirmware = this.myControl.valueChanges.pipe(
      startWith(''),
      map(val => this.filterFirmware(val))
    );

  }

  ngOnDestroy() {
    this.subcribtion.unsubscribe();
  }
}

在模板中:

<div class="form-group">
    <mat-form-field class="example-full-width">
        <input type="text" placeholder="Firmware auswählen" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto1">
        <mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFirmware">
            <mat-option *ngFor="let firmware of filteredFirmware | async" [value]="firmware">
                {{ firmware.name }}
            </mat-option>
        </mat-autocomplete>
    </mat-form-field>
</div>

<p>
  {{selected | json}}
</p>

在此解决方案中,值是整个固件对象,因此您可以从中检索任何内容。

您可以在此处找到正在运行的示例https://stackblitz.com/edit/angular-ptg4i1