gpt4 book ai didi

带有回调的 Angular @Output

转载 作者:行者123 更新时间:2023-12-05 03:00:40 25 4
gpt4 key购买 nike

是否可以使用@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
}
}

我知道,我可以在 FormComponent 中使用 @Input() 并执行如下操作:

@Input()
set submitted(val: boolean) {
this.isSubmitted = val;
}

但我想知道是否有更简单/更好的解决方案,因为isSubmitted应该是FormComponent的内部属性,应该由组件自己管理而不是它的 parent 。

最佳答案

 onSubmit() {
this.isSubmitting = true;
this.submitHandler(this.form.value).subscribe(res => {
this.isSubmitting = false;
this.cdr.markForCheck();
});
}

在上面的示例代码中,onSubmit() 函数不是无状态函数,它依赖于外部 处理程序。从测试的 Angular 来看,使函数本身不可预测。当这失败时(如果它失败了)你将不知道在哪里、为什么或如何。回调也会在组件被销毁执行。

禁用 的问题是组件使用者的外部状态。所以我只想将它作为输入绑定(bind)(就像这里的其他答案一样)。这使组件更干燥并且更易于测试。

@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));
}
}

关于带有回调的 Angular @Output,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56627003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com