ウェブサイト検索

angular - ng-bootstrap タイプアヘッド: Observable<string[]> ではなく Observable<Person[]> をどう扱うか


私はAngular/Typescriptの初心者の質問があります。

私は ng-bootstrap の typeahead で定義されている Wikipedia の例に従い、Wikipedia の呼び出しを次の GET 呼び出しを提供するカスタム REST サービスに置き換えることにしました。

  • GET /person/name/{name}

そして名前に一致する人のリストを返します。そのリストの各人は次の通りです:

Person(id:long, name:string, surname:string)

さて、TypeScriptの部分とAngularの部分では、_serviceに人物の配列を名前の文字列の配列にmap(...)すれば、すべて正常に動作します。

  • [p1, p2, p3] -> [nameP1, nameP2, ...]

しかし、_serviceでそのようにマッピングせず、ユーザーがドロップダウンの結果をクリックできるように人物のリストを返し、その後の呼び出しなしで人物の詳細を表示したいです。

なので、私のTypeScriptコンポーネントでは、現在モデルは次の通りです:

model: Observable<Person[]>;

そして検索部分は次の通りです:

search = (text$: Observable<string>) =>
        text$.pipe(
            debounceTime(300),
            distinctUntilChanged(),
            tap(() => this.searching = true),
            switchMap(term =>
                this._service.search(term).pipe(
                    tap(() => this.searchFailed = false),
                    catchError(e => {
                        this.searchFailed = true;
                        return of([]);
                    }))
            ),
            tap(() => this.searching = false),
            merge(this.hideSearchingWhenUnsubscribed)
        )

HTML の部分は次の通りです:

 <div class="input-group input-group-lg" id="person-search">
        <input name="name" id="typeahead-http" type="text" class="form-control" [class.is-invalid]="searchFailed" (selectItem)="selectedItem($event)" [(ngModel)]="model" [ngbTypeahead]="search" placeholder="Search a person"/>
        <span class="input-group-btn">
            <button class="btn btn-primary btn-lg" type="button">
              <i class="text-muted fa fa-search"></i>
            </button>
        </span>
  <div>

ドロップダウンには名前だけを表示して、ユーザーが名前をクリックしたときに対応する人を表示するにはどうすればいいですか?

回答 #1

名前を表示するための resultFormatter が必要ですが、値を選択したときに入力フィールドに [object Object] と表示されないように、名前だけを表示する inputFormatter も必要です。これらは両方ともタイプアヘッドによって提供されます。

だから、あなたのtsで、結果と入力の両方に名前を表示したいことをマークしてください:

formatter = (x: { name: string }) => x.name;

そして、これらをテンプレートで次のように使用します:

<input ... [resultFormatter]="formatter" [inputFormatter]="formatter"/>

あなたのmodelには、依然としてオブジェクト全体が含まれます。

関連記事