3

我试图让这个组件从返回可观察的服务中获取字符串数据

import { Component, OnInit, OnDestroy } from '@angular/core';
import { TabFourService } from "./tabfour.service";
import { Subscription } from "rxjs";

@Component({
    selector: 'tab-four',
    template: `
                {{title}}
              `
})

export class TabFourComponent implements OnInit, OnDestroy{
    title: string = "This is Tab four";

    subscription: Subscription;

    constructor(private tabfourService: TabFourService){}

    ngOnInit(){
        console.log("now in init");
        this.getItems();
        this.getItems();
    }

    getItems(){
        console.log("now in get items");
        this.subscription = this.tabfourService.getItems()
                                .subscribe(data => console.log("testing observable"));
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

这是一个简单的服务:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';
import { Observable } from "rxjs";

@Injectable()
export class TabFourService {
    items: string;

    private itemSource = new Subject<string>();

    constructor(){}

    itemSource$ = this.itemSource.asObservable();

    getItems(): Observable<string> {
        this.itemSource.next("aaa");
        return this.itemSource$;
    }

}

我将服务列为@NgModule() 中的提供者,以便它可以被所有组件实例共享。TabFourComponent 还有一个路由器,所以每次我导航到它时,我都应该在控制台中看到“testing observable”。但是直到我两次调用 getItems() 才显示出来。我想知道为什么它没有在第一次触发。

tabfour.component.ts:20  now in init
tabfour.component.ts:26  now in get items
tabfour.component.ts:26  now in get items
tabfour.component.ts:28  testing observable

编辑:

而在另一种情况下,服务提供来自 http.get 的数据

// in service
getLibraryFromDatabase(): Observable<any[]> {
  return this.http.get(<some url>)
             .map(data => data.json())
             .catch(this.handleError);
}

组件订阅后无需再次调用服务的方法。

// in component
ngOnInit() {
    this.subscription = this.libraryService.getLibraryFromDatabase()
                        .subscribe(libs => this.createLibs(libs));
}
4

1 回答 1

1

如果在第二次执行 getItems() 之前未调用订阅的方法,那是因为在订阅负责之前触发了事件。在 ngOnInit 方法中注册订阅,(这是做这种事情的最佳位置),然后调用触发您订阅的事件的方法:

ngOnInit() {
    this.subscription = this.tabfourService.getItems()
                            .subscribe(data => console.log("testing observable"));
    // The subscription has been taken in charge, now call the service's method
    this.tabFourService.getItems();
}
于 2016-10-20T19:16:23.030 回答