Я хочу заменить комбинированный список, используемый в JHipster (6.8.0), на поле «Автозаполнение». В блоге Антонио Гонсалвеса я нашел способ сделать это с PrimeNG , но я не хотел добавлять еще одну новую библиотеку виджетов.
Я понял, что JHipster уже использует библиотеку "Bootstrap widgets" (https://ng-bootstrap.github.io) для ввода дат с "ngb-datepicker".
Эта библиотека предоставляет компонент, позволяющий использовать функцию "Автозаполнение" с директивой "Ngb-typeahead" . Я не специалист по Angular, поэтому мне было нелегко найти лучший способ сделать это. Тем не менее, изменения, которые должны быть сделаны, являются относительно небольшими, и самое важное: это работает .
Есть изменения:
Файл JDL используется для создания примера приложения JHipster
entity Contact {
firstName String required,
lastName String required,
email String
}
entity Language {
alpha3b String required maxlength(3),
alpha2 String required maxlength(2)
name String required,
flag32 String,
flag128 String,
activated Boolean
}
relationship ManyToOne {
Contact{language(name) required} to Language
}
filter *
service all with serviceClass
paginate Contact with pagination
dto * with mapstruct
contact-update.component. html
заменить существующий элемент управления на:
<div class="form-group">
<label class="form-control-label" jhiTranslate="jhcontact2App.contact.language" for="field_language">Language</label>
<!-- <select class="form-control" id="field_language" name="language" formControlName="languageId"> -->
<!-- <option *ngIf="!editForm.get('languageId')!.value" [ngValue]="null" selected></option> -->
<!-- <option [ngValue]="languageOption.id" *ngFor="let languageOption of languages; trackBy: trackById">{{ languageOption.name }}</option> -->
<!-- </select> -->
<input type="text" class="form-control" id="field_language" formControlName="language"
placeholder="{{ 'jhcontact2App.contact.language.placeholder' | translate }}"
(selectItem)="selectedItem($event)"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
[editable]='false' />
</div>
<div *ngIf="editForm.get('language')!.invalid && (editForm.get('language')!.dirty || editForm.get('language')!.touched)">
<small class="form-text text-danger"
*ngIf="editForm.get('language')?.errors?.required" jhiTranslate="entity.validation.required">
This field is required.
</small>
</div>
contact-update.component.ts
Обновление методов ngOnInit, updateFrom, createForm
ngOnInit(): void {
this.activatedRoute.data.subscribe(({ contact }) => {
this.updateForm(contact);
// remove service call to populate Languages Collection
// this.languageService.query()
// .subscribe((res: HttpResponse<ILanguage[]>) => (this.languages = res.body || []));
});
}
updateForm(contact: IContact): void {
this.editForm.patchValue({
id: contact.id,
firstName: contact.firstName,
lastName: contact.lastName,
email: contact.email,
// Patch full Language object instead id
// languageId: contact.languageId,
language: {id: contact.languageId, name: contact.languageName}
});
}
private createFromForm(): IContact {
// get full object from form
const language: ILanguage = this.editForm.get(['language'])!.value;
return {
...new Contact(),
id: this.editForm.get(['id'])!.value,
firstName: this.editForm.get(['firstName'])!.value,
lastName: this.editForm.get(['lastName'])!.value,
email: this.editForm.get(['email'])!.value,
// languageId: this.editForm.get(['languageId'])!.value
languageId: language.id
};
}
Добавление новых функций, используемых Ngb-typeahead :
// Add formatter
formatter = (x: { name: string }) => x.name;
// the seach function
search = (text$: Observable<string>) =>
text$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.languageService.searchByName( term ))
)
// the OnSelect
selectedItem(language: ILanguage): void {
this.editForm.patchValue({
language: language.name
});
}
language.service.ts
searchByName(term: string): any {
if (term === '') {
return of([]);
}
const options = createRequestOption({ 'name.contains': term });
return this.http.get<ILanguage[]>(this.resourceUrl, { params: options });
}
Этот последний пункт не полностью удовлетворяет меня, поскольку я хотел бы повторно использовать метод, сгенерированный первоначальным запросом «компонента language.service.ts , но этот метод использует RX JS и возвращает« Observable », и я не знаю, как ждать окончания http-запроса для прохождения результат для функции .
метод начального запроса, сгенерированный
query(req?: any): Observable<EntityArrayResponseType> {
const options = createRequestOption(req);
return this.http.get<ILanguage[]>(this.resourceUrl, { params: options, observe: 'response' });
}
Если кто-нибудь может помочь мне с этим?