Angular2/material2でオートコンプリートコンポーネントを使用してサーバーからデータをフェッチしたいと思います。 ( https://material.angular.io/components/component/autocomplete )
ts
_ emailCtrl: FormControl;
filteredEmails: any;
constructor(
private companieService: CompanieService,
) {
this.emailCtrl = new FormControl();
this.filteredEmails = this.emailCtrl.valueChanges
.startWith(null)
.map(email => this.filterEmails(email));
}
filterEmails(email: string) {
this.userService.getUsersByEmail(email)
.subscribe(
res => {
return res
},
error => {
console.log(error);
}
)
}
_
html
_ <md-input-container>
<input mdInput placeholder="Email" [mdAutocomplete]="auto" [formControl]="emailCtrl" [(ngModel)]="fetchedUser.profile.email">
</md-input-container>
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let email of filteredEmails | async" [value]="email">
{{email}}
</md-option>
</md-autocomplete>
_
サービス:userService.getUsersByEmail(email)
は次の種類のデータを取得しています:
_ ['[email protected]','[email protected]','[email protected]']
_
エラーはありませんが、オートコンプリートの結果はありません。デバッガーでchrome(tab network)と表示されます)データは入力の変更ごとに正しくプルされます
私が通常使用する私の例を病気であなたに与え、
this.SearchForm.controls['city_id'].valueChanges
.debounceTime(CONFIG.DEBOUNCE_TIME)
.subscribe(name => {
this.domain = [['name', 'ilike', name]];
this.DataService.getAutoComplete('res.city', this.domain)
.subscribe(res => {
return this._filteredCity = res['result']['records']
})
})
HTML
<div class="mb-1 ml-1 mt-1" fxFlex="30">
<md-input-container style="width: 100%">
<input mdInput placeholder="Kota" (blur)="checkAutoComplete('city_id')" [mdAutocomplete]="city_id" [required]="true" [formControl]="SearchForm.controls['city_id']">
</md-input-container>
<md-autocomplete #city_id="mdAutocomplete" [displayWith]="displayFn">
<md-option *ngFor="let city of _filteredCity" [value]="city">
<span>{{ city.name }}</span>
</md-option>
</md-autocomplete>
<div *ngIf="SearchForm.controls['city_id'].hasError('required') && SearchForm.controls['city_id'].touched" class="mat-text-warn text-sm">Kolom ini wajib diisi.</div>
</div>
そのように
これは私がやった方法です。
.html
<input formControlName="search" [mdAutocomplete]="auto" type="text" class="form-control">
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let data of filteredData | async" [value]="data.text">
{{ data.text }}
</md-option>
</md-autocomplete>
.ts
filteredData: Observable<any[]>; // async pipe needs to be an Observable
myContent: any[] = [];
this.filteredData = this.myformGroup.get('search').valueChanges
.debounceTime(400)
.switchMap(value => {
// get data from the server. my response is an array [{id:1, text:'hello world'}] as an Observable
return this.myApiService.getSearch(value);
}).map(res => this.myContent = res);
これで問題が解決するかどうかお知らせください。
my.component.html
<form [formGroup]="myForm">
<mat-form-field>
<input matInput
formControlName="email"
[matAutocomplete]="autoEmailGroup"
name="email"
type="email"
placeholder="Email"
aria-label="Email" />
<mat-autocomplete
autoActiveFirstOption
#autoEmailGroup="matAutocomplete">
<mat-option
*ngFor="let email of emailOptions | async"
[value]="email">{{ email }}</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
my.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { startWith, tap, switchMap, map, filter } from 'rxjs/operators';
import { empty } from 'rxjs/observable/empty';
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
myForm: FormGroup;
emailOptions: Observable<string[]>;
constructor(
private fb: FormBuilder,
private http: HttpClient,
) { }
createForm() {
this.myForm = this.fb.group({
email: new FormControl(),
});
const _fetchEmailsFromServer = (): Observable<string[]> => {
// TODO you need to ultilize your service here
return empty();
};
this.emailOptions = this.myForm.get('email')!.valueChanges
.pipe(
startWith(''),
switchMap((input: string) => {
return _fetchEmailsFromServer().pipe(
// handle your HTTP response here
map((response: any): string[] => {
return <string[]> response!.data!.emails;
}),
tap((emails: string[]) => {
// LOGGING
console.log('Received emails:', emails);
}),
// you can filter emails fetched from your server here if you want
);
}),
).pipe(
// default value to be displayed before HTTP task is completed
startWith([]),
);
}
}
参照: