Angular 2服务从组件调用方法

时间:2017-11-21 16:29:31

标签: javascript angular angular2-services

是否可以让服务调用组件方法?

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。我不想再打个电话,所以我在Put电话的响应中得到了我想要的新数据。

来自组件的呼叫 - >组件服务 - > apiclient服务

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

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

为我工作

即使这个灵魂在我不喜欢它的时候也在为我工作,因为我必须使用我的api中的其他对象复制并粘贴许多相同“操作”的代码。例如,我认为它适用于Picture Component,但我的Movie Component也需要这个。如果我经常在项目中编写相同的代码,这通常是件坏事吗?

1 个答案:

答案 0 :(得分:3)

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

使用Observable

让服务拥有价值的知识变化并发出变化。组件在 1 上侦听一个EventEmitter,以响应值的变化。 (另见:Creating and returning Observable from Angular 2 Service

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不希望开发人员在服务上使用EventEmitters:What is the proper use of an EventEmitter?