Оберните ngx-bootstrap / typeahead в угловую директиву

Я использую ngx-bootstrap / typeahead для автозаполнения на моей странице. Это код, который я использую сейчас:

<input type="text" class="form-control" name="countryName" autocomplete="off" [(ngModel)]="asyncSelected" (blur)="typeaheadOnBlur()" [typeahead]="countryDataSource" (typeaheadOnSelect)="typeaheadOnSelect($event)" typeaheadWaitMs="300" typeaheadOptionField="name">

Составная часть:

asyncSelected: string;

constructor() {
    this.countryDataSource = Observable.create((observer: any) => {
        observer.next(this.asyncSelected);
    }).mergeMap((input: string) => this.getAutoCompleteResults(input));
}

typeaheadOnSelect(event: TypeaheadMatch): void {
    viewModel.nestedProperty.country = event.item.name;
    viewModel.nestedProperty.countryCode = event.item.countryCode;
}

typeaheadOnBlur(): void {
    viewModel.nestedProperty.country = asyncSelected;
}

getAutoCompleteResults() возвращает массив объектов (наблюдаемых) в следующем формате:

[{id: 1, name: "Australia", code: "AU"}, {id: 2, name: "United States", code: "US"}, ...]

Теперь я думаю, что код в моем компоненте не принадлежит компоненту, который просто использует автозаполнение. Это также не делает его многоразовым. Я не хочу, чтобы все эти коды в компоненте и все эти (blur)="typeaheadOnBlur()", typeaheadWaitMs="300" каждый раз, когда я хочу использовать автозаполнение, я думаю о создании директивы для его использования следующим образом:

<input [myAutoComplete] [ngModel]="viewModel.nestedProperty?.country" (NgModelChange)="viewModel.nestedProperty.country=$event" (select)="mySelectFunction(???)" />

Как вы могли заметить, я не мог использовать viewModel.nestedProperty.country для привязки к ngx-bootstrap. Похоже, этот $event имеет другую структуру, чем ngx-bootstrap $event в typeaheadOnSelect($event).

Я тоже не знаю, как обращаться с (select)="mySelectFunction(???)". Как вы предлагаете сделать это автозаполнение более удобным для моего проекта?


person hosjay    schedule 31.07.2017    source источник


Ответы (2)


Вам нужно включить тег компонента typeahead в родительский компонент и передать значения компоненту typeahead, который получает значения с помощью декоратора @Input. Я думаю, вам нужно знать, как работают компоненты Angular в целом, поскольку компоненты сами по себе разработаны таким образом, что его можно легко использовать повторно.

Компонент Typeahead HTML-

<input [id]="id" [(ngModel)]="_model" [typeahead]="workflows" (typeaheadLoading)="changeTypeaheadLoading($event)" 
(typeaheadNoResults)="TypeaheadNoResults($event)" (typeaheadOnBlur)="onBlurFunction($event)"
 [typeaheadMinLength]="MinLength" [typeaheadOptionsLimit]="OptionsLimit"
 [typeaheadOptionField]="OptionsField" [optionsListTemplate]="customListTemplate">

Компонент Typeahead-

@Component({
selector: 'app-input-typeahead',
templateUrl: './input-typeahead.component.html',
})
export class InputTypeaheadComponent{
@Input() selected: any;
@Input() workflows: any;
...
@Input() callback: Function;   
...} 

Родительский компонент

<app-input-typeahead name="requestTypeahead" [id]="workflowId" 
[label]="workflowLabel" [(ngModel)]="selectedWorkflow" [workflows]="requestMatrixList"
[OptionsField]="optionsField"[OptionsLimit]="optionsLimit" [MinLength]="minLength"
[customListTemplate]="customListTemplate" [customItemTemplate]="customItemTemplate"
[placeholder]="placeholder" [callback]="onTypeaheadHandler"></app-input-typeahead>
person coder87    schedule 16.09.2017

Вы можете расширить саму директиву TypeaheadDirective и установить желаемые значения по умолчанию. Взгляните на эту суть: https://gist.github.com/francarmona/9e7d373e80e9cc9afb9c023923093c01

person Francisco Carmona    schedule 01.10.2018