Angular 2 个服务从组件调用方法

Angular 2 service calls method from component

甚至可以让服务调用组件方法吗?

myapp.component

export class MyAppComponent {
  public value;
  ...
  public setValue(payload){
    this.value = payload;
  }
}

myapp.service

@Injectable()
export class MyAppService {
  private myAppComponent: MyAppComponent;
  private apiClientService: ApiClientService

  // ...
    After i make an PUT http call, the body from the response is my new "value"
  // ...

    putValue(payload: JSON){

    return this.apiClientService.putAPIObject(payload).then((response) => {
      this.myAppComponent.setValue(response);
    }); 
  }
}

这导致 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'setValue' of undefined

谁能解释一下我做错了什么? 提前致谢。

编辑: 由于人们抱怨我的方法,如果有人能向我解释什么是处理这个问题的最佳方法,我完全可以从头开始。

我从 api 获取值,更改它们然后将它们放回 api。我不想再次调用 get,所以我在 Put 调用的响应中得到了我想要的新数据。

调用来自组件 --> 组件服务 --> api客户端服务

我想问题是我在起点和终点之间有一个额外的服务。

编辑 2:我试图避免使用 component service 并仅使用 component --> apiclient service

使其对我有用

即使这个灵魂对我有用,目前我有点不喜欢它,因为我必须复制和粘贴大量代码以与我的 api 中的其他对象相同 "Operation" .例如,我让它适用于图片组件,但我的电影组件也需要它。如果我在一个项目中经常写相同的代码,通常是一件坏事,或者不是?

至少有几种方法可以解决这个问题,但希望这能给你一个开始。欢迎反馈和更正。

使用 Observable

让服务拥有值更改的知识并发出更改。该组件侦听 1 服务上的 EventEmitter 以对值更改做出反应。 (另请参阅:

MyAppService

import { Subject } from 'rxjs/Subject';

@Injectable()
export class MyAppService {
  private valueSource = new Subject<any>();
  public valueUpdate$ = this.valueSource.asObservable();

  putValue(payload: JSON){
    return this.apiClientService.putAPIObject(payload).then((response) => {
      /** here **/
      this.valueUpdate$.next(response);
    }); 
  }
}

MyAppComponent

export class MyAppComponent {
  public value;
  private valueSubscription;

  constructor(private _myAppService: MyAppService) {}

  ngOnInit() {
    /** and here **/
    this._myAppService.valueUpdate$.subscribe((p) => this.setValue(p));
  }
  ...
  public setValue(payload){
    this.value = payload;
  }
}

注册组件

回答原题,思路是将组件注册到服务中,以便它可以根据需要调用组件。您可以通过依赖注入获取引用,但不推荐这样做(例如,如果您的原始组件引用被破坏怎么办?)

MyAppService

@Injectable()
export class MyAppService {
  private myAppComponent: MyAppComponent;

  /** here **/
  registerMyApp(myApp: MyAppComponent) {
    this.myAppComponent = myApp;
  }

  putValue(payload: JSON){
    return this.apiClientService.putAPIObject(payload).then((response) => {
      this.myAppComponent.setValue(response);
    }); 
  }
}

MyAppComponent

export class MyAppComponent {
  public value;

  /** and here **/
  constructor(myAppService: MyAppService) {
    myAppService.registerMyApp(this);
  }
  ...
  public setValue(payload){
    this.value = payload;
  }
}
  1. 感谢 AJT_82 注意到 Angular 不希望开发人员在服务上使用 EventEmitter: