Angular async * ng在选择后不起作用

时间:2018-01-11 11:52:42

标签: angular typescript rxjs rxjs-lettable-operators

与角度和可观察力斗争。

我有这样的观察:

 private searchResults: Observable<any[]>;

我把它称之为:

this.searchResults = this.searchTerms.pipe(
        map((event: any) => event.target.value),
        debounceTime(300),
        distinctUntilChanged(),
        filter((term: string) => term && term.length >= 3),
        flatMap((term: string) => this.http.get<any[]>(`https://my-cool-rest.api/${term}`))
    )

(注意:searchTerms为Subject<string>(),并在html上实现,如:<input type="text" (keyup)="searchTerms.next($event)"/>

到目前为止一切都还可以,一切都按预期工作。

当我收到结果时,我会用简单的UL

显示它们
<ul>
     <li *ngFor="let result of searchResults | async">
          <a (click)="selectItem(result.id)>{{ result.name }}</a>
     </li>
</ul>

单击某个项目将调用在控制台上写入结果的selectItem函数并清除searchResults

selectItem(result: string) {
    if (result) {
        console.log(result);
        this.searchResults = Observable.of([]);
    }
}

同样,一切都很好。

但如果我重复搜索其他关键字的过程,则*ngFor不再显示结果。

为了完全安全,我订阅了searchResults(例如:在构造函数中)来记录它

constructor() {
     this.searchResults.subscribe(data => console.log(data));
}

并猜猜是什么?像魅力一样工作

我认为这是一种我不理解的角度(5+)行为。

提前致谢!

1 个答案:

答案 0 :(得分:1)

正如未定义的用户所指出的那样,你用这一行覆盖了流:

this.searchResults = Observable.of([]);

因此,如果您想重置阵列,您有两种选择:
  - 将“搜索”输入设置为空字符串,但是我会触发另一个请求   - 利用可观察量和流组合

我认为第二个是更好的主意,以下是如何实现它:

import { merge } from 'rxjs/observable/merge';
import { mapTo } from 'rxjs/operators';

private searchResults: Observable<any[]>;
private resetResults$ = new Subject();

this.searchResults = merge(
  // every time the reset stream receive a new value,
  // merge it into the searchResults and no matter what 
  // the value is merge an empty array
  resetResults$.pipe(mapTo([])),

  this.searchTerms.pipe(
    map((event: any) => event.target.value),
    debounceTime(300),
    distinctUntilChanged(),
    filter((term: string) => term && term.length >= 3),
    flatMap((term: string) => this.http.get<any[]>(`https://my-cool-rest.api/${term}`))
  )
)

selectItem(result: string) {
  if (result) {
    // send a new value to the reset stream
    this.resetResults$.next();
  }
}