.subscribe到BehaviourSubject <any>没有在Angular 5中触发

时间:2018-04-06 12:06:58

标签: angular

我正在尝试订阅我正在编写的服务,因此我可以在语言下拉列表更改时更新import { Component } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { TranslationEmitterService } from '../../services/translation.emitter.service'; @Component({ selector: 'app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [ TranslationEmitterService ] }) export class AppComponent { constructor(private translate: TranslateService, private translationService: TranslationEmitterService) { translate.addLangs(["en", "pt", "fr"]); translate.setDefaultLang('pt'); let browserLang = translate.getBrowserLang(); translate.use(browserLang.match(/en|pt|fr/) ? browserLang : 'en'); } } 输入。

我发现的stackoverflow问题是;

basic example

然而,当我实现这个时,订阅方法没有解雇?我有以下内容;

我的app.component.ts;

<div class="dropdown">
    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Select Language
    </button>
    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
        <a class="dropdown-item" (click)="switchLanguage('pt')"><span class="flag-icon flag-icon-gr"></span> Portugese</a>
        <a class="dropdown-item" (click)="switchLanguage('en')"><span class="flag-icon flag-icon-gr"></span> English</a>
        <a class="dropdown-item" (click)="switchLanguage('fr')"><span class="flag-icon flag-icon-gr"></span> French</a>
    </div>
</div>

我的组件html;

import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class TranslationEmitterService {
    private _languageChangedSource = new BehaviorSubject<any>(0);
    languageChange$ = this._languageChangedSource.asObservable();


    changeLanguage(lang) {
        console.log("in change language " + lang);
        this._languageChangedSource.next(lang);
    }
}

我的观察服务;

import { Injectable, Inject, Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

import { TranslationEmitterService } from '../../../services/translation.emitter.service';

@Component({
    selector: 'nav-menu',
    templateUrl: './navmenu.component.html',
    styleUrls: ['./navmenu.component.css']
})
export class NavMenuComponent {
    public isCollapsed = true;
    public status = false;

    constructor(private translate: TranslateService, private translationEmitterService: TranslationEmitterService) {

    }

    public switchLanguage(language: string) {
        console.log("switching language");
        this.translate.use(language);
        this.translationEmitterService.changeLanguage(language);
    }
}

用于切换调用更改的语言的组件;

ngOnInit() {

    this.translationSubscription = this.translationService.languageChange$.subscribe(

        // lang => this.refreshAutoCompleteItems(lang)
        x => console.log(x)
    );
}

最后我订阅了我的组件中的事件;

switchLanguage

该组件的副本位于Delegation: EventEmitter or Observable in Angular

否,当我触发switching language方法时,我得到输出in change language fr和{{1}}输出,但是组件观察没有触发?

有谁能告诉我这里我做错了什么?

3 个答案:

答案 0 :(得分:1)

问题的一个可能原因是两个组件中的每一个都有自己的服务实例。当一个组件调用changeLanguage服务方法时,另一个组件不会收到通知,因为它已订阅了另一个服务实例。

为了确保两个组件共享一个服务实例,它应该只提供一次。这可以通过仅在模块级别提供服务并将其从组件的providers列表中删除来实现:

@NgModule({
    providers: [
        TranslationEmitterService 
    ],
    ...
})
export class AppModule {
}

答案 1 :(得分:0)

您需要map您的服务电话。

this._languageChangedSource.next(lang).map(r=>r.json());

this.translationEmitterService.changeLanguage(language).map(r=>r.json());

当您在组件中使用订阅时,需要使用地图。

此外,您的服务必须返回Observable。您的组件方法可以subscribe

答案 2 :(得分:0)

检查下面的演示

Working Demo

private _languageChangedSource = new BehaviorSubject<any>(0);

在实例化BehaviorSubject时,您已将0作为初始值传递。这就是为什么你的初始值为0的原因。

注意 在实例化BehaviorSubject时,我们需要提供一个默认值。这是必须的。

this.switchLanguage("test");

我通过test作为switchLanguage函数参数,我得到了以下日志。

switching language
in change language test
test

我希望这能解决你的问题。如果您有任何问题,请告诉我。