如何在 Angular 中将回调函数(带有 http 请求)从父组件传递到子组件
How pass a callback funcion (with a http request) from a parent component to child component in Angular
我想传递一个函数,该函数具有来自父组件的 http 请求到子组件,并从子组件执行请求。
我的代码如下:
// myService
constructor(private http: HttpClient)
getIds(id) {
// return of(['a', 'b', 'c', id]); with this works
return this.http.get(apiUrl) // with this doesnt work
}
// parentComponent.ts
callbackFunction = this.myService.getIds;
constructor(private myService: MyService) { }
// parentComponent.html
<child-component [callbackRequest]="callbackFunction"></child-component>
// childComponent.ts
@Input() callbackRequest;
ngOnInit() {
this.callbackRequest('d');
}
最让我困惑的是,如果我从服务中 return 构建了一个可观察对象,如果它有效的话。
调试时,我看到服务调用是否到达。
我得到的错误如下:
错误类型错误:无法读取未定义的 属性 'get'
你可以做到:
// myService
constructor(private http: HttpClient)
getIds(id) {
// return of(['a', 'b', 'c', id]); with this works
return this.http.get(apiUrl) // with this doesnt work
}
// parentComponent.ts
callbackFunction = this.myService.getIds.bind(this.myService);
constructor(private myService: MyService) { }
// parentComponent.html
<child-component [callbackRequest]="callbackFunction"></child-component>
// childComponent.ts
@Input() callbackRequest;
ngOnInit() {
this.callbackRequest('d');
}
.bind(this) 是解决方案,因为该函数将能够使用父实例(您可以看到,当您不绑定它时,一切都变成未定义的)
getIds
函数中 this
关键字的含义在使用 Angular 中的 @Input
绑定传递它的引用时丢失。它在你 return of([...])
时起作用,因为没有使用 this
。请参阅 here 以了解有关 this
关键字在回调
中的含义的规范 post
有两种解决方案
- 使用
bind
- 请参阅来自@GabrielSereno 的 post
- 使用箭头函数
服务
public getIds = (id) => {
return this.http.get(apiUrl);
}
组件
callbackFunction: any;;
constructor(private myService: MyService) { }
ngOnInit() {
this.callbackFunction = this.myService.getIds;
}
模板
<ng-container *ngIf="callbackFunction">
<child-component [callbackRequest]="callbackFunction"></child-component>
</ng-container>
是否有使用回调函数的特定原因?
通常我会尝试让一个组件“聪明”,一个组件“笨”。
在您的情况下,parent 决定做什么(哪个 HTTP 请求),而 child 决定何时做。也许 child 也应该显示结果。
因此我决定在类似的情况下,我的 child 将在 运行 请求的时间通知 parent,然后 parent 运行 请求并将结果提供给 child.
是的,这样我 child 不仅需要一个输入,还需要一个输入和一个输出。另一方面,我的 child 有一个清晰定义的 INPUT 接口。如果我只提供回调方法,回调可能 return 任何东西。
我的 child 也几乎没有“逻辑”。所有的魔法都在 parent 中。这使得为 child 组件编写单元测试变得非常容易。对于 parent 也很简单,只需模拟 child.
是的,JavaScript(因此也包括 TypeScript)允许 .bind()
之类的东西。但根据我的经验,它似乎很快就解决了一个问题,但真正的努力是在后面。它更难理解,也更难调试。所以我通常会避免它。
只是另一种解决问题的方法。选择您喜欢的部分并忽略其余部分:-
)
我想传递一个函数,该函数具有来自父组件的 http 请求到子组件,并从子组件执行请求。
我的代码如下:
// myService
constructor(private http: HttpClient)
getIds(id) {
// return of(['a', 'b', 'c', id]); with this works
return this.http.get(apiUrl) // with this doesnt work
}
// parentComponent.ts
callbackFunction = this.myService.getIds;
constructor(private myService: MyService) { }
// parentComponent.html
<child-component [callbackRequest]="callbackFunction"></child-component>
// childComponent.ts
@Input() callbackRequest;
ngOnInit() {
this.callbackRequest('d');
}
最让我困惑的是,如果我从服务中 return 构建了一个可观察对象,如果它有效的话。 调试时,我看到服务调用是否到达。 我得到的错误如下: 错误类型错误:无法读取未定义的 属性 'get'
你可以做到:
// myService
constructor(private http: HttpClient)
getIds(id) {
// return of(['a', 'b', 'c', id]); with this works
return this.http.get(apiUrl) // with this doesnt work
}
// parentComponent.ts
callbackFunction = this.myService.getIds.bind(this.myService);
constructor(private myService: MyService) { }
// parentComponent.html
<child-component [callbackRequest]="callbackFunction"></child-component>
// childComponent.ts
@Input() callbackRequest;
ngOnInit() {
this.callbackRequest('d');
}
.bind(this) 是解决方案,因为该函数将能够使用父实例(您可以看到,当您不绑定它时,一切都变成未定义的)
getIds
函数中 this
关键字的含义在使用 Angular 中的 @Input
绑定传递它的引用时丢失。它在你 return of([...])
时起作用,因为没有使用 this
。请参阅 here 以了解有关 this
关键字在回调
有两种解决方案
- 使用
bind
- 请参阅来自@GabrielSereno 的 post
- 使用箭头函数
服务
public getIds = (id) => {
return this.http.get(apiUrl);
}
组件
callbackFunction: any;;
constructor(private myService: MyService) { }
ngOnInit() {
this.callbackFunction = this.myService.getIds;
}
模板
<ng-container *ngIf="callbackFunction">
<child-component [callbackRequest]="callbackFunction"></child-component>
</ng-container>
是否有使用回调函数的特定原因?
通常我会尝试让一个组件“聪明”,一个组件“笨”。
在您的情况下,parent 决定做什么(哪个 HTTP 请求),而 child 决定何时做。也许 child 也应该显示结果。
因此我决定在类似的情况下,我的 child 将在 运行 请求的时间通知 parent,然后 parent 运行 请求并将结果提供给 child.
是的,这样我 child 不仅需要一个输入,还需要一个输入和一个输出。另一方面,我的 child 有一个清晰定义的 INPUT 接口。如果我只提供回调方法,回调可能 return 任何东西。
我的 child 也几乎没有“逻辑”。所有的魔法都在 parent 中。这使得为 child 组件编写单元测试变得非常容易。对于 parent 也很简单,只需模拟 child.
是的,JavaScript(因此也包括 TypeScript)允许 .bind()
之类的东西。但根据我的经验,它似乎很快就解决了一个问题,但真正的努力是在后面。它更难理解,也更难调试。所以我通常会避免它。
只是另一种解决问题的方法。选择您喜欢的部分并忽略其余部分:- )