Резюме: у меня есть выпадающий поиск по полю, который вы вводите. Когда я выбираю из раскрывающегося списка, который успешно устанавливает поле для объекта, который я получил при поиске, но, к сожалению, регистрирует ЭТО изменение и отправляет весь объект для поиска.
HTML:
<form [formGroup]="myForm" novalidate>
<mat-form-field>
<input matInput
placeholder="SKU / Item Number"
[matAutocomplete]="auto"
formControlName='itemName'>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="parseDropDownSelection">
<mat-option
*ngFor="let row of searchQueryResult"
[value]="row"
(onSelectionChange)="onItemSelection($event)">
<span>{{ row.Name }}</span>
</mat-option>
</mat-autocomplete>
</form>
Настройка:
import {FieldSearchServiceItem} from './../services/field-search.service';
constructor(
private dialog: MatDialog,
private formBuilder: FormBuilder,
private http: HttpClient,
private appServiceItem: FieldSearchServiceItem,
) {}
ngOnInit ()
ngOnInit(){
this.myForm = this.formBuilder.group
({
itemName: '',
});
this.myForm
.get('itemName')
.valueChanges
.pipe(
debounceTime(200),
switchMap(value => this.appServiceItem.search({name: value}, 1))
)
.subscribe(serviceResult => this.searchQueryResult = serviceResult.qResult);
}
Сервис:
@Injectable()
export class FieldSearchServiceItem
{
constructor(private http: HttpClient) {}
search(filter: {name: string} = {name: ''}, page = 1): Observable<apiQueryResponseForItem>
{
var queryResponse;
return this.http.get<apiQueryResponseForItem>(`example.com/search/item/${filter.name}`)
.pipe(
tap((response: apiQueryResponseForItem) =>
{
response.qResult = response.qResult
.map(unit => new ItemUnit(unit.Id, unit.Name))
return response;
})
);
}
}
Определения класса:
export class ItemUnit
{
constructor
(
public Id:number,
public Name:string,
) {}
}
export interface apiQueryResponseForItem
{
qSuccess: boolean;
qResult: ItemUnit[];
}
Я видел другие ответы, в которых решение заключалось в использовании emitEvent: false при установке значения, например:
this.myForm.get('itemName').patchValue('theDataThatCameBackFromSeach', {emitEvent:false})
Это имеет смысл ... но я чувствую это решение не соответствует этому подходу наблюдаемых / инъекционных / материалов ... в основном потому, что я не использую вызов, который выполняет .setValue () или .patchValue (), я предполагаю, что где-то в Материальный материал, который это обрабатывает.
Сервер, в конце концов, видит такие вызовы:
http://example.com/search/item/a (when the letter a is typed)
http://example.com/search/item/[object%20Object] (after clicking the dropdown, JS tries to search 'object' after clumsily falling back to string representation )
Мой onItemSelection()
в настоящее время не задействован, он работает, но ничего не делает, кроме сброса на консоль. .qResult
, возвращаемый моей службой searchQueryResult
, содержит {Id:number,Name:string}
. Как я могу сделать так, чтобы действие настройки поля автозаполнения по-прежнему выполняло свою работу по настройке поля, но не создавало событие изменения, когда оно это делает, при этом соблюдая onItemSelection()
, чтобы я мог получить свой другая обработка сделана?