简体   繁体   English

Angular共享服务-订阅将未定义传递给组件

[英]Angular Shared Service - Subscribe passes undefined to component

I am attempting to implement the singleton design pattern by using a shared service so that all components are able to receive the updated global variable provided by the service. 我正在尝试通过使用共享服务来实现单例设计模式,以便所有组件都能够接收该服务提供的更新的全局变量。

The result is that it will update without issue when called from app component, but no component receives the value when subcribing to: 结果是,当从应用程序组件调用时,它将进行更新而不会出现问题,但是在订阅以下内容时,没有组件会接收到该值:

colorString$ = this.colorSource.asObservable();

The method used to subscribe which is not returning a value: 不用于返回值的订阅方法:

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

This is the service: 这是服务:

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

This is the app.component: 这是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);
  }
  }

This is the component which the app component loads: 这是应用程序组件加载的组件:

app.component.html: app.component.html:

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

navigation.component 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)
  }
}

And finally I have a router outlet, which loads from navigation: 最后,我有一个路由器插座,可从导航中加载:

navigation.component.html navigation.component.html

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

about.component 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 );
    });
}
}

The output of console with all of the logging when loading the page is: 加载页面时,带有所有日志记录的控制台输出为:

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

When accessing about, it is not called to subscribe either - I don't yet understand the lifecycle of the router outlet regarding OnInit and its constructors. 访问时,也不会调用订阅-我还不了解有关OnInit及其构造函数的路由器出口的生命周期。

It now works using a Behavior Subject instead of a subject: 现在可以使用行为主题代替主题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM