JHipster:通过用具有可观察性的 NgbTypeahead 替换 ComboBox 来实现自动完成
JHipster : implement AutoComplete by replacing ComboBox with a NgbTypeahead with observable
我想用 "Autocomplete" 字段替换 JHipster(6.8.0) 中使用的组合框,我在 Antonio Goncalves's 博客上找到了方法用 PrimeNG 来做,但我不想添加另一个新的 Widgets 库。
我意识到 JHipster 已经在使用 "Bootstrap widgets" 库 (https://ng-bootstrap.github.io) 来输入带有 "ngb-datepicker" 的日期。
此库提供了一个组件,允许使用 "Ngb-typeahead" 指令实现 "Autocomplete" 功能。
我不是 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
接触-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>
接触-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组件的"initial query generated method",但是这个方法使用了RXJS和returns一个"Observable"和我不知道如何等待http请求结束将结果传递给函数。
初始查询生成方法
query(req?: any): Observable<EntityArrayResponseType> {
const options = createRequestOption(req);
return this.http.get<ILanguage[]>(this.resourceUrl, { params: options, observe: 'response' });
}
有谁能帮我解决这个问题吗?
终于,我找到了重用 JHispter 生成的 "query()" 方法的方法!
像这样:
// the search function
search = (text$: Observable<string>) =>
text$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => term.length < 2 ? [] : this.languageService.query({ 'name.contains': term })),
map((res: HttpResponse<ILanguage[]>) => (res.body || []))
);
searchByName() 方法不再需要。
我想用 "Autocomplete" 字段替换 JHipster(6.8.0) 中使用的组合框,我在 Antonio Goncalves's 博客上找到了方法用 PrimeNG 来做,但我不想添加另一个新的 Widgets 库。
我意识到 JHipster 已经在使用 "Bootstrap widgets" 库 (https://ng-bootstrap.github.io) 来输入带有 "ngb-datepicker" 的日期。
此库提供了一个组件,允许使用 "Ngb-typeahead" 指令实现 "Autocomplete" 功能。 我不是 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
接触-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>
接触-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组件的"initial query generated method",但是这个方法使用了RXJS和returns一个"Observable"和我不知道如何等待http请求结束将结果传递给函数。
初始查询生成方法
query(req?: any): Observable<EntityArrayResponseType> {
const options = createRequestOption(req);
return this.http.get<ILanguage[]>(this.resourceUrl, { params: options, observe: 'response' });
}
有谁能帮我解决这个问题吗?
终于,我找到了重用 JHispter 生成的 "query()" 方法的方法!
像这样:
// the search function
search = (text$: Observable<string>) =>
text$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => term.length < 2 ? [] : this.languageService.query({ 'name.contains': term })),
map((res: HttpResponse<ILanguage[]>) => (res.body || []))
);
searchByName() 方法不再需要。