angular2(rc1)Observables无效

时间:2016-09-09 21:43:20

标签: events angular observable angular2-services

我想要两个不同的组件,有两个不同的路由,我想将信息从componentA传递给componentB。 我做了以下事情: 1 - 创建处理事件的服务 2-在componentA上设置信息并传递给Service事件 3-尝试在componentB

获取此信息

我的服务:

@Injectable()
export class TokenService{
private tokenSource = new Subject<Object>();
token$ = this.tokenSource.asObservable();

setToken(token: string) {
  this.tokenSource.next(token);
}

ComponentA:

@Component({
selector: 'login',
templateUrl: './login.html',
providers: [TokenService],
moduleId: module.id
})

export class LoginCmp {
   constructor(private tokenService: TokenService) {
}

someMethod() {
    this.tokenService.setToken('some dinamyc value');
}
....

以componentB:

@Component({
selector: 'cabecalho',
moduleId: module.id,
templateUrl: './cabecalho.html',
providers: [TokenService]
})

constructor(private tokenService: TokenService) {
tokenService.token$.subscribe(
  data => {
    console.log(data);

  });
}

当我从ComponentA设置一些信息时,我的控制台永远不会打印出我在ComponentB上放置的console.log(data)

2 个答案:

答案 0 :(得分:0)

如果您在每个组件上提供服务,则无法获得共享服务。每个组件都有自己的服务实例。

Angular2为每个提供商维护一个实例。如果您在共享父组件上提供服务(最终共享父组件为AppComponent)或将其传递给bootstrap(AppComponent, [TokenService]),那么它们将获得注入的相同实例。

答案 1 :(得分:0)

首先,您的组件正在使用TokenService的不同实例。您需要在它们之间使用共享服务。

其次,componentB在componentA中设置了 之后的主题。如果您在设置值时未订阅主题,则您将无法获得该值。如果您打算在订阅之前设置该值,则应该使用BehaviourSubject。订阅BehaviourSubject将允许您接收设置的最后一个值以及后续值。

第三,使用asObservable意味着您不希望能够接下来使用tokenSource的值。但是,您有一个可以执行此操作的功能,并且可以从componentB访问。我建议将tokenSource设置在一个单独的服务中,该服务将在ComponentA和tokenService之间共享。

您可以尝试以下方法。创建共享服务:

@Injectable()
export class SharedService {
    tokenSource = new BehaviorSubject<Object>('initial value');

    setToken(token: string) {
        this.tokenSource.next(token);
    }
}

在AppComponent引导程序函数中初始化SharedService的共享实例。

bootstrap(AppComponent, [ SharedService ]);

创建TokenService。将SharedService的实例传递给TokenService的构造函数(Donot将SharedService添加到[providers],因为它将创建一个新实例):

@Injectable()
export class TokenService {
    token$: any;
    constructor(sharedService: SharedService) {
        this.token$ = sharedService.tokenSource.asObservable();
    }

ComponentA(同样,不要在[providers]中指定SharedService。因此Angular2将搜索层次结构,直到找到SharedService的实例。)

@Component({
    selector: 'compA',
    templateUrl: '/compA.html',
})

export class ComponentA {
    constructor(private sharedService: SharedService){
        console.log('CompA');
        this.sharedService.setToken('some dynamic value');
    }
}

ComponentB创建一个新的TokenService实例。

@Component({
    selector: 'compB',
    templateUrl: '/compB.html',
    providers: [TokenService]
})

export class ComponentB implements OnDestroy {
    sub: any;
    constructor(private tokenService: TokenService) {
        console.log('CompB');
        this.sub = tokenService.token$.subscribe(
            data => {
                console.log(data);
            });
    }

    ngOnDestroy() {
        if (this.sub)
            this.sub.unsubscribe();
    }
}

因此,您有一个公开tokenSource值的共享服务。以及一个返回一个可观察序列的tokenService,从而隐藏了源序列。还有一个组件(B)可以订阅此序列并获取已设置的最后一个值和后续值,因为您使用的是BehaviourSubject而不是Subject。