【问题标题】:Angular - Update a service's property from a componentAngular - 从组件更新服务的属性
【发布时间】:2018-08-01 23:41:11
【问题描述】:

我有一个带有appName 属性的服务。当我的组件执行 POST 时,我试图将组件的名称传递给服务的 appName 属性,从而在服务中更新它,以便当服务稍后调用此属性时,它具有我从组件。

但是,我无法更新服务的 appName 属性 - 它与最初在服务中定义的一样:

error-logger.service.ts

  constructor(private http: HttpClient) { 

  };

    appName = "initialName";

//logError function fires on error from GlobalErrorHandlerService, logging errors and passing the new appName value from component.
    logError() {
    //below should log the new appName (from component), not the initial
    console.log("Application:" + this.appName);
    }

}

my-component.component.ts

import { Component, OnInit } from '@angular/core';
import { ErrorLoggerService } from '../../../core/services/error-logger.service';
import { Router, ActivatedRoute } from '@angular/router';

...

  constructor(
    private errorLoggerService: ErrorLoggerService,
    private route: ActivatedRoute,
    private router: Router
    ) {
      console.log("COMPONENT NAME: " + this.route.component.name);
    }



  ngOnInit() {
    this.errorLoggerService.appName = "NewAppName";
    this.errorLoggerService.postData(JSON.stringify(myData))
    .subscribe(
      data => console.warn(data),
      error => {throw error},
      () => console.log("empty")
    );
  }

global-error-handler.service.ts

import { Injectable, ErrorHandler, Injector } from '@angular/core';
import {ErrorLoggerService} from '../services/error-logger.service';
import { HttpErrorResponse } from '@angular/common/http';

// Global error handler for logging errors
@Injectable()
export class GlobalErrorHandlerService extends ErrorHandler {
    constructor(private injector : Injector) {


        super();
    }

    handleError(error: any) {
      let loggerService = this.injector.get(ErrorLoggerService);
      loggerService.logError(error)    
      .subscribe(
        data => console.warn(data),
        error => {throw error},
        () => console.log("empty")
      );

  }
}

如何从组件中正确更新服务的属性?要么我有一些根本性的错误,要么可能与我在error-logger.service.ts中所做的RXJS/自定义错误处理的异步性质有关。

【问题讨论】:

  • 您的服务是如何注册的?它在模块的providers 数组中吗?还是在组件中?
  • 是的,该服务是全局的,并在app.module.ts providers 数组中注册。
  • 在哪里调用 logError?
  • 我已经更新了我的答案以包含正在调用“logError”的文件。正在从全局 global-error-handler.service.ts 文件调用 logError,该文件也在 app.module.ts 中全局注册。这个 global-error-handler 覆盖 Angular 的默认 ErrorHandler,代表它提供自定义错误处理。嗯...这让我想,也许我的errorLogger 服务在组件传递新属性值之前在global-error-handler.service.ts 中被实例化...
  • 我不熟悉这种语法,所以希望其他人可以加入。但有两种可能性...... 1)不知何故,这种语法提供了服务的多个实例。 2) 你正在失去 this.

标签: angular service dependency-injection error-handling custom-error-handling


【解决方案1】:

我认为这段代码对你有用:

第一个'error-logger.service.ts':

中转换你的appName
public appName = new BehaviorSubject<string>('initialName')

logError(error) {
   return appName.pipe(tap(appName => console.log(appName)))
   // or
   //return appName.pipe(switchMap(appName=> {
   //     console.log(appName)
   //     return of('{data}')
   // }))
}

第二个my-component.component.ts:

this.errorLoggerService.appName.next('otherName')

第三个 GlobalErrorHandlerService:

loggerService.logError(error)    
  .subscribe(
    appName => console.warn(appName),
    // or data => console.warn(data)
    error => {throw error},
    () => console.log("empty")
  );

我的想法有效,希望如此有效:)

【讨论】:

  • hmm...我已经连接了所有这些,但我仍然得到 appName 的相同 initialName 值。
  • 为什么不尝试将ErrorLoggerService放在GlobalErrorHandlerService的构造函数中?
  • 谢谢。我相信我已经尝试过了,但我会再次尝试使用您的代码。作为一个普遍的问题,为什么需要所有这些新的 RXJS 逻辑(点击、管道等)才能从组件更新服务的属性?是不是因为在我的旧代码中,RXJS 数据流的异步特性以某种方式取代了我从组件中设置该属性?
  • 首先,管道是具有任何可观察值的属性或函数,它用于转换观察对象内部信息的操作,在点击的情况下,它用于获取和使用可观察值中的值,这意味着当您订阅该 BehaviorSubject 时,您会使用该值(在我的代码中打印组件名称)并在 susbcribe 函数(在 GlobalErrorHandlerService 中)中获取相同的值。
  • 其次,observable(BehaviorSubject 或 Subject)有一些函数来更新 observable 的值(比如 next(),将值传递给下一个观察者),这给了更新这个值的可能性在仅执行该函数的任何组件中,订阅该值的观察者在更改时获取该值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多