JHipster:通过将ComboBox替换为可观察到的NgbTypeahead来实现自动完成

问题描述 投票:1回答:1

我想用[自动完成]字段替换JHipster(6.8.0)中使用的组合框,我在Antonio Goncalves's博客上找到了使用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组件的“初始查询生成的方法”,但是此方法使用RXJS并返回“ Observable”和我不知道如何等待http请求结束以将结果传递给函数

初始查询生成方法

  query(req?: any): Observable<EntityArrayResponseType> {
    const options = createRequestOption(req);
    return this.http.get<ILanguage[]>(this.resourceUrl, { params: options, observe: 'response' });
  }

如果有人可以帮助我吗?

angular jhipster ng-bootstrap
1个回答
0
投票

最后,我找到了一种方法,可以重用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()方法不再需要。

© www.soinside.com 2019 - 2024. All rights reserved.