javascript - 延迟加载模块每次加载时都会创建父服务的多个实例

标签 javascript angular typescript

每次我从 MainComponent 导航到 TestListComponent 时,都会触发 TestListComponent 构造函数并创建 ObservableService 的新实例。当我单击链接时,控制台显示重复的消息。也许是一个 Angular 问题,有帮助吗?

main.module.ts

 import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser'; 
    import {MainRoutingModule} from "./main-routing.module"; 
    import {MainComponent}   from './main.component';  
    import {ObservableService} from "../../core/services/observable.service";

    @NgModule({
        imports: [
            BrowserModule,
            MainRoutingModule,                   
        ],
        declarations: [MainComponent],
        providers: [ObservableService],
        bootstrap: [
            MainComponent
        ]
    })
    export class MainModule { }

main.routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

export const routes: Routes = [
    { path: 'tests', loadChildren: 'angular/app/modules/test-list/test-list.module#TestListModule'},
    { path: '**', redirectTo: '' }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class MainRoutingModule {}

observable.service.ts

import { Injectable } from '@angular/core';
import {Subject} from "rxjs/Rx";
import 'rxjs/add/operator/map'


@Injectable()
export class ObservableService {

    // Observable string sources
    private changeLanguageStatus = new Subject<Object>();

    // Observable string streams
    changeLanguageStatus$ = this.changeLanguageStatus.asObservable();

    constructor(){}

    /**
     * Change language event
     * @param params
     */
    changeLanguageEvent(params: Object){
        this.changeLanguageStatus.next(params);
    }        
}

test-list.module.ts

import { NgModule } from '@angular/core';       
import {TestListComponent} from "./test-list.component";

@NgModule({
    declarations: [
        TestListComponent
    ]
})
export class TestListModule {}

test-list.component.ts

import {Component} from '@angular/core';
import 'rxjs/Rx';
import {ObservableService} from "../../core/services/observable.service";

@Component({
    moduleId: module.id,
    selector: 'st-test-list',
    templateUrl: 'test-list.component.html'
})

export class TestListComponent {

    constructor(private observableService:ObservableService) {
        observableService.changeLanguageStatus$.subscribe(
            data => {
                console.log('Test', data);
            });
    }    
}

main.component.ts

import {Component, ViewChild} from '@angular/core';
import 'rxjs/Rx';

import {ObservableService} from "../../core/services/observable.service"; 

@Component({
    moduleId: module.id,
    selector: 'st-main',
    templateUrl: 'main.component.html'       
})

export class MainComponent {      
   constructor(private observableService:ObservableService) {} 

   changeLanguage(lang){
      this.observableService.changeLanguageEvent({type: lang});
   }  
}

main.component.html

<a href="" (click)="changeLanguage('en')"></a>

<!--Dynamic content-->
<router-outlet></router-outlet>

最佳答案

当您通过路由导航到组件时,它会被创建,而当您导航回来时,它会被销毁,这应该是预期的行为。据我所知,您遇到这个问题是因为您正在创建所谓的“无限可观察”,即您正在订阅它并等待事件流,在您的情况下更改语言。因为您永远不会取消订阅 Observable,所以订阅它的函数对于组件的每个新实例都保持事件状态。因此,rxjs 不会处理您的订阅的处理,您必须自己处理。

首先,我建议您阅读有关生命周期 Hook 的内容。查看 OnInit 和 OnDestroy 生命周期 Hook 。

使用 ngOnInit 订阅您的 Observable 并使用 ngOnDestroy 取消订阅,如下所示:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

@Component({ .... })

export class TestListComponent implements OnInit, OnDestroy
{ 
    private _languageSubscription : Subscription;

    ngOnInit(): void 
    {
        this._languageSubscription = observableService.changeLanguageStatus$.subscribe(
        data => {
            console.log('Test', data);
        }); 
    }

    ngOnDestroy() : void 
    {
        this._languageSubscription.unsubscribe();   
    }

}

希望这能解决您的问题。

关于javascript - 延迟加载模块每次加载时都会创建父服务的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42476439/

相关文章:

javascript - 在 Javascript 中动态调用函数

javascript - 如何使用 CSS 定位 Firefox 和 IE?

JavaScript:DRY mouseover/mouseout 事件处理程序

javascript - 基于 Angular 中的 promise 结果取消间隔

ANGULAR 如何推送到可观察数组?英雄 : Observable<Hero[]>

javascript - 隔离外部Javascript,防止污染?

Angular 替换方法不适用于字符串

javascript - 监听 Angular 对象更新的变化

没有模块加载器的 typescript ?

javascript - TypeScript:模块和具有静态成员的类有什么区别?