如何绑定到Angular Material Autocomplete下拉列表中的Id,但按字符串表示形式

时间:2018-03-08 09:10:19

标签: angular angular-material

我有一个Angular Material Autocomplete下拉列表,其中包含一个按CustomerName过滤的过滤器。

这是通过我的getAllCustomers()方法返回的客户实现的。然后,我loop通过每个Customer push CustomerName array进入新的filteredOptions,这基本上成为我的object

我的问题是:如何通过搜索CustomerName来实现此过滤器,但是绑定到每个客户的ID?

在我最终要保存的Customer.Id中,我想要保存CustomerName而不是object array

我尝试创建一个包含CustomerNameId的新filteredOptions,但这不适用于filterfilter方法。似乎array方法只使用单个值的objects,而不是HTML

另外,我需要在fileredOptions

中正确绑定

以下是我的基本object实施:(注意:我包含了我希望使用的{name: element.CustomerName, id: element.Id} element.CustomerName。这不能解释。工作方法只需将array推入filteredOptions: Observable<string[]>; constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { } ngOnInit() { this.getAllCustomers(); } filter(val: string): string[] { return this.customerNameArray.filter(option => option.toLowerCase().indexOf(val.toLowerCase()) === 0); } getAllCustomers() { this.loadDataService.getAllCustomers() .subscribe(data => { this.customerArray = data; let thisArray = []; this.customerArray.forEach(element => { thisArray.push({name: element.CustomerName, id: element.Id}); }); this.customerNameArray = thisArray; this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe( startWith(''), map(val => this.filter(val)) ); }); }

即可
HTML

这是我的<mat-form-field> <input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto"> <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete"> <mat-option *ngFor="let option of filteredOptions | async" [value]="option"> {{ option }} </mat-option> </mat-autocomplete> </mat-form-field>

JSON.stringify()

1 个答案:

答案 0 :(得分:0)

If you use an object for your options, you will need to modify your filter function and filteredOptions to use the object and not a string array. You will also need to use the displayWith feature of mat-autocomplete to allow the input to work with the object. A stackblitz example is here.

Your code:

export class Customer{
    constructor(public CustomerName: string, public Id: number) { }
}

...

filteredOptions: Observable<Customer[]>;

constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }

ngOnInit() {
    this.getAllCustomers();
}

filter(val: any) {
    let name = val.CustomerName || val; // val can be Customer or string
    return this.customerNameArray.filter(option => option.CustomerName.toLowerCase().indexOf(name.toLowerCase()) === 0);
}

getAllCustomers() {
    this.loadDataService.getAllCustomers()
    .subscribe(data => {
        this.customerArray = data;
        let thisArray = [];
        this.customerArray.forEach(element => {
            thisArray.push(new Customer(element.CustomerName, element.Id));
        });
        this.customerNameArray = thisArray;
        this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
            startWith(null),
            map(val => this.filter(val))
        );
    });
}

displayCustomer(cust: Customer) {
    return cust ? cust.CustomerName : '';
}

HTML:

<mat-form-field>
    <input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto">
        <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [displayWith]="displayCustomer">
            <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
            {{ option.CustomerName }}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>