检查 Angular 6 组件中的自定义回调

Checking custom callback in Angular 6 component

我正在使用一个 Angular 2+ 向导组件(我在 Angular 6 上),我将其分叉到我的项目中并对其进行了大量模板和样式自定义。不幸的是,我选择的那个不支持其他向导中的 canExit 功能,所以我试图添加它。它能够在步骤中验证表单,所以当我需要做的不仅仅是简单的字段验证时,我通常可以添加另一个自定义验证函数:

<custom-wizard>
  <wizard-step [title]='Step 1' [isValid]='step1Form.valid && validateStep1()'>
    <form>....

问题是由于 Angular 的观察和我假设的变化检测,它被重复调用。通常这不是问题,但我只想在他们点击 Next 时进行一次服务器端验证。反复调用它是行不通的。

所以我认为我需要将回调函数作为参数传递给子向导步骤组件:

<custom-wizard>
  <wizard-step [title]='Step 1' [isValid]='step1Form.valid' [canExit]='validateStep1()'>
    <form>....

在父组件中,我创建了验证函数:

validateStep1(){
    console.log('calling server...');
    // assume this is a server-side call, returning true/false
    return serverValidationPassed();
}

在我添加的向导步骤组件中:

@Input() canExit: boolean = true;

在自定义向导中,我检查此回调是否失败,如果失败则阻止正常的步骤更改:

public next(): void {
    if(!this.activeStep.canExit){
        console.log('failed!');
        return;
    }
    else {
        //proceed to next step as usual
    }
}

问题是验证仍然被调用了很多次,我又回到了开始的地方!我读到过使用 @Output 来传递函数,所以我尝试了这种方法:

<custom-wizard>
  <wizard-step [title]='Step 1' [isValid]='step1Form.valid' (canExit2)='validateStep1()'>
    <form>....

在向导步骤中:

    @Output() canExit2: EventEmitter<any> = new EventEmitter<any>();

在向导的下一个函数中:

    public next(): void {
    if(!this.activeStep.canExit2.emit()){
        console.log('failed!');
        return;
    }
    else {
        //proceed to next step as usual
    }
}

验证步骤现在只调用一次,很好。但即使 validateStep1 通过,我在 if 检查中也会失败。我相信这是因为发射不会 return 任何东西,而是广播。这对我来说是新领域。有人可以指出我在这里做错了什么以及我如何执行这个额外的验证吗?

如果其他人遇到过类似的事情,我想出了我的问题。我的根本问题是我本质上是在尝试进行同步服务器端检查,但使用的是模板驱动的表单。我从 Angular 文档中阅读了有关 Reactive 表单的内容,这就是问题所在——在表单被认为有效之前对给定的表单字段执行自定义验证。

因此我根本不需要弄乱向导组件,现在我可以根据服务调用的结果将表单标记为无效。更好的是,它只会在字段满足表单标准后调用验证(在我的例子中,一旦输入的长度正确,就会尝试进行额外的验证)。

这是对执行自定义异步验证的一个很好的概述,他唯一遗漏的是您需要将 ReactiveFormsModule 导入到您的模块中:

https://alligator.io/angular/async-validators/