【问题标题】:Component not getting updated data when sharing Data between components with a Service使用服务在组件之间共享数据时组件未获取更新的数据
【发布时间】:2019-08-29 17:54:59
【问题描述】:

我想将brandName 变量从同级组件用于同一模块中的另一个组件。我尝试过使用BehaviorSubject

但是,虽然我可以将更新后的 brandName 发送到我的服务,但我的组件仍然使用默认消息。

我的服务文件如下所示:

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

import { BehaviorSubject } from 'rxjs';


@Injectable()

export class DataService {


  private messageSource = new BehaviorSubject('default message');

  currentMessage = this.messageSource.asObservable();


  constructor() { }

  changeMessage(message: string) {

    console.log('service sent: ' + message);

    this.messageSource.next(message);

  }

}

控制台在这里打印出更新的消息。

但是,当我尝试在 Order 组件中更新我的变量时,我得到了“默认消息”

Order.component.ts:


import {DataService} from '../services/data.service';

...
export class OrderComponent implements OnInit {
...

constructor(...private data: DataService)

...

this.data.currentMessage.subscribe(message => this.brandName = message);

console.log('brandname');

console.log(this.brandName);

打印出“默认消息”

只有它们的共同父 app.module.ts 包含 DataService 提供程序。

编辑

我也尝试从第三个组件中获取变量,使用:

this.data.currentMessage.subscribe(message => this.brandName = message);

实际上,在这个中确实获得了更新的品牌名称,但在它所针对的组件中仍然没有任何内容,即使两个组件都是同一级别的兄弟。

此外,我尝试使用重新制作服务

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

@Injectable({
  providedIn: 'root',
})
export class DataService {

  private data: string;

  setOption(value) {

    this.data = value;
    console.log('service sent: ' + value + 'and data ' + this.data );
  }

  getOption() {
    console.log('service returned');
    console.log(this.data);
    return this.data;


  }

但是,我在服务获取更新值时遇到了同样的问题,第三个组件可以获取这个更新的值,但我的服务打算用于的组件获取默认值。

【问题讨论】:

  • 你能拼凑出一个stackblitz显示错误的功能吗?

标签: angular typescript behaviorsubject


【解决方案1】:

尝试像下面这样声明服务以拥有一个实例(添加providedIn: 'root'

@Injectable({
  providedIn: 'root',
})
export class DataService {


  private messageSource = new BehaviorSubject('default message');

  currentMessage = this.messageSource.asObservable();


  constructor() { }

  changeMessage(message: string) {

    console.log('service sent: ' + message);

    this.messageSource.next(message);

  }
}

并且由于服务是异步调用的,console.log(this.brandName); 是在服务工作结束之前调用的,所以我建议将日志记录 this.brandName 值移到订阅中:

this.data.currentMessage.subscribe(message => {
 this.brandName = message;
 console.log(this.brandName); // will show the new message
});

console.log('brandname');

console.log(this.brandName); // will show the default message

我创建了一个包含您的代码的 Stackblitz 应用程序,并且共享服务在其中工作:https://stackblitz.com/edit/angular-ele1cu

【讨论】:

  • 我尝试在 Injectable 中添加providedIn,但我仍然收到默认消息。
  • 我更改消息的组件在 Order.component 订阅消息之前加载是否意味着它不起作用?
  • 感谢您的回答 Mohamed,不幸的是我仍然从 this.data.currentMessage.subscribe(message => { this.brandName = message; console.log(this.brandName); // will show the new message }); 获得默认值我已经编辑了我的原始帖子并提供了更多信息
  • 从您的代码中我注意到您没有调用 changeMessage 方法,我创建了一个工作堆栈闪电战:stackblitz.com/edit/angular-ele1cu
【解决方案2】:

服务文件

import { Observable, Subject, } from 'rxjs';


@Injectable({providedIn: 'root'})

export class DataService {

  // private messageSource = new BehaviorSubject('default message');
  // currentMessage = this.messageSource.asObservable();

  private messageSource = new Subject<string>();

  constructor() { }

  /*changeMessage(message: string) {
    console.log('service sent: ' + message);
    this.messageSource.next(message);
  }*/

  setMessage(message: string) {
    this.messageSource.next(message);
  }

  getMessage() {
    return this.messageSource.asObservable();
  }
}

使用服务中的getMessage方法订阅你的组件中消息的变化,使用setMessage方法设置消息

【讨论】:

    【解决方案3】:

    您必须将此服务作为更高(模块)级别的单例提供。您似乎有两个不同的此服务实例。

    【讨论】:

      猜你喜欢
      • 2018-10-12
      • 2016-05-18
      • 2017-11-06
      • 2021-05-03
      • 2017-07-22
      • 1970-01-01
      相关资源
      最近更新 更多