角色共享服务 - 订阅将undefined传递给组件

时间:2017-04-22 22:01:17

标签: angular

我试图通过使用共享服务来实现单例设计模式,以便所有组件都能够接收服务提供的更新的全局变量。

结果是,从app组件调用时它会更新而不会出现问题,但是当订阅到以下内容时,没有任何组件会收到该值:

colorString$ = this.colorSource.asObservable();

用于订阅但未返回值的方法:

  constructor( private sharedSer : SharedColorService ) {
    sharedSer.Update(this.myColor);
  }

这是服务:

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

@Injectable()
export class SharedColorService {

  // Observable string source
private colorSource = new Subject<string>();

// Observable string stream
colorString$ = this.colorSource.asObservable();

// Service message commands

Update(input:string) {
   this.colorSource.next(input);
   console.log("Service Color: " + input);
}
}

这是app.component:

import { Component, OnInit } from '@angular/core';
import {SharedColorService} from './sharedColor.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  colors = ["#31b0d5", "#d55631", "#d531b0", "#31d556"]
  myColor = this.colors[Math.floor(Math.random()*this.colors.length)];

  constructor( private sharedSer : SharedColorService ) {
    console.log("I can log");
    console.log("App Color: " + this.myColor);
    sharedSer.Update(this.myColor);
  }
  }

这是app组件加载的组件:

app.component.html:

<h1>APP: {{myColor}}</h1>
<app-navigation></app-navigation>

navigation.component

import { Component, OnInit, Injectable } from '@angular/core';
import {SharedColorService} from '../sharedColor.service';
@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css'],
})

export class NavigationComponent{
  myColor: string;
  errors;
  constructor(private _sharedService: SharedColorService){
    console.log("I AM TRYING TO SUBSCRIBE");
    this._sharedService.colorString$.subscribe(
     result => {
        console.log('Navigation received result: ', result);
        this.myColor = result;
      });
        console.log('Navigation after subscribe: ', this.myColor)
  }
}

最后我有一个路由器插座,从导航加载:

navigation.component.html

<a class="col-sm-2" routerLink="/about" routerLinkActive="active">About</a>
<router-outlet></router-outlet>

about.component

import { Component, OnInit } from '@angular/core';
import {SharedColorService} from '../sharedColor.service';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

myColor: string;
constructor(private _sharedService: SharedColorService){}

ngOnInit() {
  this._sharedService.colorString$.subscribe(
    data => {
      this.myColor = data;
          console.log("About received color: " + this.myColor + " Data: " + data );
    });
}
}

加载页面时带有所有日志记录的控制台输出是:

I can log
app.component.ts:15 App Color: #31d556
sharedColor.service.ts:16 Service Color: #31d556
navigation.component.ts:15 I AM TRYING TO SUBSCRIBE
navigation.component.ts:21 Navigation after subscribe:  undefined

访问about时,也不会调用它来订阅 - 我还不了解路由器插座关于OnInit及其构造函数的生命周期。

1 个答案:

答案 0 :(得分:0)

现在使用行为主题而不是主题:

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

@Injectable()
export class SharedColorService {

  // Observable string source
private colorSource: BehaviorSubject<string>= new BehaviorSubject<string>("#d55631");

// Observable string stream
colorString$ = this.colorSource.asObservable();

// Service message commands
Update(input:string) {
   this.colorSource.next(input);
   console.log("Service Color: " + input);
}

}

CONSOLE.LOG

app.component.ts:14 I can log
app.component.ts:15 App Color: #31b0d5
sharedColor.service.ts:17 Service Color: #31b0d5
navigation.component.ts:13 I AM TRYING TO SUBSCRIBE
navigation.component.ts:16 Navigation received result:  #31b0d5
navigation.component.ts:19 Navigation after subscribe:  #31b0d5
core.es5.js:3025 Angular is running in the development mode. Call 
about.component.ts:18 About received color: #31b0d5 Data: #31b0d5