Angular 尝试在使用管道之前等待一个可观察对象发出/初始化

Angular 尝试在使用管道之前等待一个可观察对象发出/初始化,angular,rxjs,ng-bootstrap,Angular,Rxjs,Ng Bootstrap,我使用ngbtypeahead作为一个自动完成搜索选项,用户键入一些内容,这个键入的值被发送到父组件,然后父组件调用服务器,返回的值(可观察的)然后被传递回子组件。 我试图做的是,只要我的typeAhead组件从父组件(显示为自动完成选项的结果)接收到数据作为@input,就用switchMap(我的管道末端)发出,数据是调用服务器的结果。最初(在键入任何内容之前)数据为空,因此typeAhead组件对数据有一个未定义的值。 我的问题是,我第一次键入似乎发生的情况是,管道在typeAhead(子

我使用ngbtypeahead作为一个自动完成搜索选项,用户键入一些内容,这个键入的值被发送到父组件,然后父组件调用服务器,返回的值(可观察的)然后被传递回子组件。 我试图做的是,只要我的
typeAhead
组件从父组件(显示为自动完成选项的结果)接收到
数据作为
@input
,就用
switchMap
(我的管道末端)发出,
数据是调用服务器的结果。最初(在键入任何内容之前)
数据
为空,因此
typeAhead
组件对
数据
有一个未定义的值。 我的问题是,我第一次键入似乎发生的情况是,
管道在typeAhead(子)组件接收到
数据之前完成,这导致它显示自动完成选项。下面是我的代码,我的主要问题是我的
handleTypeahead
函数有什么问题,当我在AUTCOMPLE中键入时,它没有发出键入的值

import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {Observable, of} from "rxjs";
import {
  debounceTime,
  delayWhen,
  distinctUntilChanged, filter,
  last,
  map,
  mergeMap,
  switchMap,
  tap,
  withLatestFrom,
} from "rxjs/operators";
import {FilterService} from "@carebox/core";
import {ISearchCriteria} from "@carebox/core";
import {NgbTypeaheadSelectItemEvent} from "@ng-bootstrap/ng-bootstrap";

@Component({
  selector: 'core-ui-typeahead-filter',
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './typeahead-filter.component.html',
})
export class TypeaheadFilterComponent implements OnInit {
  @Input() id: string;
  @Input() name: string;
  @Input() caption: string;
  @Input() placeholder: string;
  @Input() cssClass: string;
  @Input() cssStyle: string;
  @Input() function: any;

  @Input() data: Observable<string[]>

  model: any;




  @Output() onTypeahead: EventEmitter<any> = new EventEmitter<any>();
  @Output() onSelect: EventEmitter<any> = new EventEmitter<any>();


  constructor() {
  }




  handleTypeahead = (text$: Observable<string>) => {
    this.data.subscribe(
      (data) => {
        if (data) {
          return text$.pipe(
            distinctUntilChanged(),
            debounceTime(200),
            filter(term => term !== ''),
            tap((term) => console.log("handleTypeahead", term)),
            tap((term) => this.onTypeahead.emit(term)),
            /*map((term: string) => [])*/
            /*map((term: string) => term === '' ? [] : this.data)*/
            // withLatestFrom(this.data),
            switchMap(() => this.data)
          );
        }
      }
    )

  }
handleSelectItem(item) {
  this.onSelect.emit(item);
}

ngOnInit() {
  // this.data.subscribe()
}

}

以及(父级的)模板:



我有点难以理解问题所在。我敢肯定,在您订阅的内容解决之前,
subscribe()
是不可能执行的。听起来好像有两个组件在起作用——父组件和子组件——但只有其中一个的共享代码。你能创建一个MVP来演示这个问题吗?@JeffryHouser添加了更多的代码,希望这能澄清问题。这里有太多不相关的代码,所以很难理解。你应该做一个测试。但是你不能用管道(filter(data=>!!data))
过滤掉空值吗?@ritaj我不是想过滤掉
null
值,我想让管道等到
数据
有一个值。目前,数据是在有值之前发出的,如果我只是过滤,那么它不会发出任何东西。基本上,这一行应该等待数据:
switchMap(()=>this.data)
实际上@ritaj comment,是您在具有非空值之前进行可观察的等待的答案。在数据不为空之前,您的流不会继续。对我来说,了解问题是什么有点困难。我敢肯定,在您订阅的内容解决之前,
subscribe()
是不可能执行的。听起来好像有两个组件在起作用——父组件和子组件——但只有其中一个的共享代码。你能创建一个MVP来演示这个问题吗?@JeffryHouser添加了更多的代码,希望这能澄清问题。这里有太多不相关的代码,所以很难理解。你应该做一个测试。但是你不能用管道(filter(data=>!!data))
过滤掉空值吗?@ritaj我不是想过滤掉
null
值,我想让管道等到
数据
有一个值。目前,数据是在有值之前发出的,如果我只是过滤,那么它不会发出任何东西。基本上,这一行应该等待数据:
switchMap(()=>this.data)
实际上@ritaj comment,是您在具有非空值之前进行可观察的等待的答案。在数据不为空之前,流不会继续。
<div class="form-group">
<label class="label-filters" for="{{id}}">
  {{caption}}
</label>

  <input id="{{id}}"
         name="{{name}}"
         type="text"
         placeholder="{{placeholder}}"
         class="{{cssClass}}"
         style="{{cssStyle}}"
         autocomplete="off"
         [(ngModel)]="model"
         [ngbTypeahead]="handleTypeahead"
         (selectItem)="handleSelectItem($event.item)"
  >
</div>
 /* NctId Filter */
  public NctIdTypeahead(term: string) {
    this.model.NctIdList = [];

    if (!(term && term.length > 0)) {
      return;
    }

    this.searchCriteria.nctIdPrefix = term;
    this.searchCriteria.aggregateOn = 'nctid';
    this.filterService.GetNctIdFilterData(this.searchCriteria).pipe(
      last(),
      map((result: any) => {
        return result.nctid;
      })
    ).subscribe(id => this.NctIdList = of(id))

  }
<div class="col-sm-6 col-md-4 col-lg-3">
    <core-ui-typeahead-filter
      id="NctIdFilter"
      caption="NCT ID"
      placeholder="Type to select NCT ID"
      i18n-placeholder="@@T-trials.trial_protocol_id_filter_placeholder"
      [data]="NctIdList"
      [cssClass]="'form-control'"
      (onTypeahead)="NctIdTypeahead($event)"
      (onSelect)="NctIdSelect($event)">
    </core-ui-typeahead-filter>
  </div>