angular - 带有回调的 Angular @Output
问题描述
是否可以与 进行回调@Output
?
我有一个FormComponent
检查有效性,并在提交时禁用提交按钮。现在我想在提交完成后重新启用提交按钮。
@Component({
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
...
</form>
`
})
class FormComponent {
form: FormGroup = ...;
isSubmitting = false;
@Output()
submitted = new EventEmitter<MyData>()
onSubmit() {
if(this.form.invalid || this.isSubmitting) {
return;
}
this.isSubmitting = true;
this.submitted.emit(this.form.value);
// Here I'd like to listen for the result of the parent component
// something like this...
// this.submitted.emit(...).subscribe(res => this.isSubmitting = false);
}
}
@Component({
template: `
<my-form (submitted)="onSubmitted($event)"></my-form>
`
})
class ParentComponent {
constructor(private service: MyService) { }
onSubmitted(event: MyData) {
this.service.doSomething(event).pipe(
tap(res => console.log("service res", res)
);
// basically I'd like to `return` this `Observable`,
// so the `FormComponent` can listen for the completion
}
}
我知道,我可以使用@Input()
insideFormComponent
并执行以下操作:
@Input()
set submitted(val: boolean) {
this.isSubmitted = val;
}
但我想知道是否有更简单/更好的解决方案,因为isSubmitted
应该是 的内部属性FormComponent
,它应该由组件本身而不是其父级管理。
解决方案
onSubmit() {
this.isSubmitting = true;
this.submitHandler(this.form.value).subscribe(res => {
this.isSubmitting = false;
this.cdr.markForCheck();
});
}
在上面的示例代码中,该函数onSubmit()
不是无状态函数,而是依赖于外部处理程序。从测试的角度来看,使函数本身不可预测。如果失败(如果失败),您将不知道在哪里、为什么或如何。在组件被销毁后,回调也会被执行。
被禁用的问题是组件使用者的外部状态。所以我只是把它变成一个输入绑定(就像这里的其他答案一样)。这使组件更干燥,更容易测试。
@Component({
template: `<form [formGroup]="form" (ngSubmit)="form.valid && enabled && onSubmit()"</form>`
})
class FormComponent {
form: FormGroup = ...;
@Input()
enabled = true;
@Output()
submitted = new EventEmitter<MyData>()
onSubmit() {
// I prefer to do my blocking in the template
this.submitted.emit(this.form.value);
}
}
这里的主要区别是我enabled$ | async
在下面使用来支持OnPush
更改检测。由于组件的状态是异步更改的。
@Component({
template: `<my-form [enabled]="enabled$ | async" (submitted)="onSubmitted($event)"></my-form>`
})
class ParentComponent {
public enabled$: BehaviorSubject<boolean> = new BehaviorSubject(true);
constructor(private service: MyService) { }
onSubmitted(event: MyData) {
this.enabled$.next(false);
this.service.doSomething(event).pipe(
tap(res => this.enabled$.next(true)
).subscribe(res => console.log(res));
}
}
推荐阅读
- gitlab - 在 GitLab CI/CD 设置中定义变量以禁用管道中的作业的正确方法
- r - R:省略号中的最后一个参数
- java - 文本到语音 Android 工作室 - Kotlin 不起作用
- java - 不与特定表关联的实体的命名查询
- c# - 通过在 C# 中注入对象值(即使用反射)来解析字符串公式
- javascript - 如何在索引文件中动态导入/导出组件?
- python - Miniconda3 environment.yml 错误:“发现冲突!正在寻找不兼容的包。”
- php - Laravel Sanctum 在尝试获取经过身份验证的用户时返回 401
- c# - 在 ASP.NET Core MVC 中一次验证两个属性
- python - 使用熊猫根据特定顺序对重复列重新排序