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

时间:2017-02-27 01:29:09

标签: javascript angular typescript

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

  

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);
    }        
}
  

测试list.module.ts

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

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

测试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>

1 个答案:

答案 0 :(得分:1)

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

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

使用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();   
    }

}

我希望这能解决你的问题。