【问题标题】:Angular : Observable not workingAngular:可观察到的不起作用
【发布时间】:2017-06-20 12:24:01
【问题描述】:

我不完全知道出了什么问题,但我正在尝试从 angular doc 应用搜索系统,但没有成功。

这是组件中使用的函数:

// my-comp.component.ts
public testing: Observable<any>;
private searchTerms = new Subject<string>();

search(term: string): void {
    this.searchTerms.next(term.toUpperCase());
}

每次我在搜索框中输入内容时都会点击此功能,所以这里没有问题。

这里是 ngOnInit 方法:

// my-comp.component.ts
ngOnInit(): void {

    this.testing = this.searchTerms
        .debounceTime(300)        // wait 300ms after each keystroke before considering the term
        .distinctUntilChanged()   // ignore if next search term is same as previous
        .switchMap(term => term   // switch to new observable each time the term changes
            // return the http search observable
            ? this.refundCaseService.search(term)
            // or the observable of empty heroes if there was no search term
            : this.test(term)
        )
        .catch(error => {
            // TODO: add real error handling
            console.log(error);
            return Observable.of<any>();
        });

}

test(term: string) {
    console.log(term);
    return Observable.of<any>();
}

这段代码永远不会到达,它没有进入服务也没有测试功能(我使用断点和console.log来确定)。

我不明白这是怎么回事。

使用: 角 4.0.0 Angular-cli 1.0.6

【问题讨论】:

  • 所以你订阅了 this.testing?

标签: angular typescript


【解决方案1】:

其他答案是正确的,这确实是一个 Cold Observable。但是,这实际上起作用的原因是 Angular 的 async 管道。

示例中使用的async 管道:

<div id="search-component">
  <h4>Hero Search</h4>
  <input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
  <div>
    <div *ngFor="let hero of heroes | async"
         (click)="gotoDetail(hero)" class="search-result" >
      {{hero.name}}
    </div>
  </div>
</div>

因为这个管道,这个例子是有效的。

异步管道订阅 Observable 或 Promise 并返回它发出的最新值。当发出新值时,异步管道会标记要检查更改的组件。当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。

来源:https://angular.io/api/common/AsyncPipe


tl;dr:您无法调试此代码,因为它正在模板/html 中处理。

【讨论】:

  • @Robouste 很高兴我能帮上忙 :-)
【解决方案2】:

您必须订阅 Observable,否则它不会“监听”更改。

   this.testing.subscribe(
        x => console.log('onNext: %s', x),
        e => console.log('onError: %s', e),
        () => console.log('onCompleted')
    );

【讨论】:

  • 当我这样做时,我得到了cannot read property 'subscribe' of undefined。我应该把它放在哪里使它起作用?感谢@echonax,我知道我可以通过异步管道订阅,但我怎样才能在组件内部进行呢?
  • @Robouste 你可以在定义this.testing = 部分后完成
  • 我觉得自己很笨,谢谢。我认为这是异步的,但它不是
【解决方案3】:

THOUGHTRAM - Cold vs Hot Observables 上查看来自 Christoph Burgdorf 的这篇精彩文章。

基本上,您在此处处理的内容被称为 Cold Observable

Cold observables 在订阅后开始运行,即 observable 序列仅在订阅时才开始向观察者推送值 叫。 (...) 这与鼠标移动等热可观察对象不同 甚至在之前就已经产生价值的事件或股票代码 订阅处于活动状态。

因此,除非您订阅 this.testing 或在模板中使用 async 管道,否则不会触发任何请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    • 2022-01-04
    • 2017-05-17
    相关资源
    最近更新 更多