【问题标题】:How to deal with Observables in rxjs and angular 5 , problem with bootstrap typeahead implementation如何处理 rxjs 和 angular 5 中的 Observables,bootstrap typeahead 实现的问题
【发布时间】:2018-10-23 14:05:14
【问题描述】:

我正在尝试在 Angular 5 中实现自动完成(引导输入)。

经过几次代码重构,我得到了迄今为​​止最好的结果。但是在发出新值(在输入中输入新术语)之后,它就出现了这个错误......

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at Object.subscribeToResult (subscribeToResult.js:74)
at SwitchMapSubscriber.push../node_modules/rxjs/operators/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:103)
at SwitchMapSubscriber.push../node_modules/rxjs/operators/switchMap.js.SwitchMapSubscriber._next (switchMap.js:96)
at SwitchMapSubscriber.push../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:90)
at DistinctUntilChangedSubscriber.push../node_modules/rxjs/operators/distinctUntilChanged.js.DistinctUntilChangedSubscriber._next (distinctUntilChanged.js:103)
at DistinctUntilChangedSubscriber.push../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:90)
at DebounceTimeSubscriber.push../node_modules/rxjs/operators/debounceTime.js.DebounceTimeSubscriber.debouncedNext (debounceTime.js:98)
at AsyncAction.dispatchNext (debounceTime.js:114)
at AsyncAction.push../node_modules/rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
at AsyncAction.push../node_modules/rxjs/scheduler/AsyncAction.js.AsyncAction.execute (AsyncAction.js:86)

这是我的代码:

private searchTerm = new Subject<string>();
public termsArray: any = [];
constructor(private apiService: DataService){
       const result$ = this.searchTerm
       .debounceTime(100)
       .distinctUntilChanged()
       .switchMap(term => this.apiService.getSearchTest(term))
           .subscribe(result => {
                      this.termsArray = result.suggestions as Array<any>;
                      console.log(this.termsArray);
                      }
                      , err => console.log(err))
}

autocompleteTest = (text$: Observable<string>) =>
    text$.pipe(
        debounceTime(300),
        distinctUntilChanged(),
        map(term => term.length < 1 ? []
            : this.termsArray
                .filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
                .slice(0, 10))
        )

onKeyUpSearch(searchText: string){
    if (searchText !== "") this.searchTerm.next(searchText);
}

【问题讨论】:

  • 你的 getSearchTest 方法定义是什么

标签: angular twitter-bootstrap rxjs bootstrap-typeahead


【解决方案1】:

通常你有两件事

private searchTerm = new Subject<string>();
observableSearchTerm=this.searchTerm.asObservable()

你在 searchTerm 上做了“下一个”,但是从 observable 订阅

onKeyUpSearch(searchText: string){
    if (searchText !== "") this.searchTerm.next(searchText);
}
//But subscribe to the "Observable" 
 this.observableSearchTerm
   .debounceTime(100)
   .distinctUntilChanged()
   .switchMap(term => this.apiService.getSearchTest(term))
       .subscribe(result => {
          ...
   }

注意 1:在 RxJs 6 (Angular 6) 中,您必须使用管道更改代码

 this.observableSearchTerm.pipe(
   debounceTime(100),
   distinctUntilChanged(),
   switchMap(term => this.apiService.getSearchTest(term))
 ).subscribe(result => {
          ...
 }

注意 2:您可以使用 FromControl 并直接订阅值更改

//In .html
<input type="text" [formControl]="control">

//In .ts
control:FormControl=new FormControl()  //Define the control
//..after in ngOnInit
ngOnInit()
{
   this.control.valueChanges.pipe(
      debounceTime(100),
      distinctUntilChanged(),
      switchMap(term => this.apiService.getSearchTest(term)
   ).subscribe(result=>{
     ....
   })
 }

stackblitz

【讨论】:

  • 感谢您的回答和很好的解释,但还是一样。我认为问题出在 ngbtypeaaead 函数上,上面的名称为 autocompleteTest
猜你喜欢
  • 1970-01-01
  • 2014-10-08
  • 2018-11-24
  • 2021-02-18
  • 2021-12-22
  • 2016-06-05
  • 2020-02-10
  • 1970-01-01
  • 2016-12-03
相关资源
最近更新 更多