是否可以让服务调用组件方法?
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也需要这个。如果我经常在项目中编写相同的代码,这通常是件坏事吗?
答案 0 :(得分:3)
至少有几种方法可以解决这个问题,但希望这会给你一个开始。打开反馈和更正。
让服务拥有价值的知识变化并发出变化。组件在 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;
}
}