从多个组件更新服务数据 - Observable subscribe

时间:2016-12-09 16:37:10

标签: javascript html angular observable angular2-services

我想在输入网站的每个页面后在固定的Navbar文件中显示页面标题

文件结构:

-navbar.ts         (where I display the title, import current title from service)
-titles.service.ts (store the current title )
-component_one.ts  (Send title 1 to service)
-component_two.ts  (Send title 2 to service)

navbar.ts文件

import { Component, OnInit,} from '@angular/core';
import { Subscription } from "rxjs";
import {TitleService} from './titles.service';
import {component_one} from '../component_one';
import {component_two} from '../component_two';


@Component({
selector: '[navbar]',
template: require('./navbar.html'),
providers:[TitleService, component_one, component_two]
})

export class Navbar implements OnInit {
 title_page: any;
 _subscription: any;

 constructor(public com_one: component_one, public _titleService:TitleService,  public com_two: component_two){

  this.title_page = _titleService.title_page;
  this._subscription = _titleService.titleChange.subscribe((value) => { 
    this.title_page = value; 
  });  //it's ok?

  }

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

titles.service.ts

import {Component, Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Subject } from 'rxjs/Subject';
import { Subscription } from "rxjs";


@Injectable()
export class TitleService {
  title_page: any;


  titleChange: Subject<string> = new Subject<string>(); //it is ok?

  constructor() {
  this.title_page = "default title string"; 
  }

  change(title){
  this.title_page = title;
  this.titleChange.next(this.title_page);  //I think is not working
  }
}

component_one.ts文件 (加载此页面后,我想在导航栏html文件上显示'TITLE OF COMPONENT ONE'

import {Component} from '@angular/core';
import {TitleService} from '../core/navbar/titles.service';

@Component({
selector: '[component_one]',
template: require('./component_one.html')
providers: [TitleService]
})

export class component_one{
title_page: any;

  constructor(public http: Http, public _titleService: TitleService){
   this.title_page = _titleService.title_page;
   this.changeMyTitle(); //Update Title
  }

  changeMyTitle() {
  this._titleService.change('TITLE OF COMPONENT ONE');
  }

}

component_two.ts文件(与具有不同标题字符串的component_one相同,加载此页面后,我想在导航栏html文件上显示'TITLE OF COMPONENT two'

import {Component} from '@angular/core';
import {TitleService} from '../core/navbar/titles.service';

@Component({
selector: '[component_two]',
template: require('./component_one.html')
providers: [TitleService]
})

export class component_two{
title_page: any;

  constructor(public http: Http, public _titleService: TitleService){
   this.title_page = _titleService.title_page;
   this.changeMyTitle(); //Update Title
  }

  changeMyTitle() {
  this._titleService.change('TITLE OF COMPONENT TWO');
  }

}

进入第一页(第一部分)后仍然显示'TITLE OF COMPONENT TWO',我做错了什么?

1 个答案:

答案 0 :(得分:3)

如果您在每个组件TitleService部分内使用providers,它将创建该服务的新实例(providers: [TitleService]

所以不要这样做:

@Component({
selector: '[component_one]',
template: require('./component_one.html')
providers: [TitleService]
})

而是将服务移至@NgModule providers,以便该模块中的每个组件都具有相同的提供程序实例:

@NgModule({
  imports: [ BrowserModule ],
  providers: [MyService]
  declarations: [ App, AnotherApp ],
  bootstrap: [ App ]
})

完整示例:https://plnkr.co/edit/qMnXG7oxF3SdTptKHUen?p=info

对于旧版本,

将共享服务放在bootstrap函数中以在整个应用程序中共享它:

bootstrap(App, [MyService]);