【问题标题】:Angular 7 service communication between components组件之间的Angular 7服务通信
【发布时间】:2019-12-31 22:34:44
【问题描述】:

我正在创建带有步骤的向导。我有两个没有父子关系的组件:

  1. 带有提交按钮的页脚组件正在重定向到下一步。
  2. 对某些输入进行验证的表单组件。

我还为上述两个组件之间的通信创建了一个服务。

我想要实现的是在页脚提交按钮上调用方法,该方法将检查来自组件编号 2 的表单是否有效。如果是,我们可以进行下一步,如果不是,我需要调用验证错误,而不进行下一步,直到用户将一些信息传递给表单上的输入。

我不确定如何实现这一点。有什么想法吗?谢谢。

我尝试在按钮上调用验证,但在同一个表单组件中。它按预期工作。现在我想在页脚的提交按钮上调用这个方法。

这是我在页脚组件中的onSubmitStep() 方法:

public onSubmitStep() {
    if (this.currentStep < this.maxSteps) {
        this.currentStep += 1;
        this.switchStep();
        this.showDefaultFooter = false;
    }
}

这是我的表单组件中的内容:

public contractPropertiesContent: ContractPropertiesInput;
public contractPropertiesForm: FormGroup;

constructor(private fb: FormBuilder, private router: Router, private contractPropertiesService: ContractPropertiesService) {}

ngOnInit() {
    this.contractPropertiesContent = this.contractPropertiesService.getContractPropertiesContent();
    this.contractPropertiesForm = this.initFormGroup();
}

private initFormGroup() {
    return this.fb.group({
        paymentConditionsInput: ['', Validators.required],
        creditDaysInput: ['', Validators.required],
        targetInput: ['', Validators.required]
    });
}

【问题讨论】:

  • 我建议你在 Stackblitz 上创建一个工作示例,它确实会帮助我们更好地解决它。
  • 您好,感谢您的回复。我已经为上面的意思准备了结构:stackblitz.com/edit/angular-6kdkjx
  • 酷,我正在检查它
  • 您真的需要将按钮和表单放在单独的组件中吗?
  • 不幸的是,按钮在页脚组件中,而表单是分开的。如果我可以将这两个合二为一,那将很容易:D

标签: angular service communication


【解决方案1】:

补充评论(查看基于您的stackblitz 的简单堆栈闪电战

在你的 form.component 中

  ngOnInit() {
    this.myService.customObservable
       .pipe(filter((x:any)=>x.command)
       .subscribe(res=>{
         if (res.command=="check")
         {
           this.contractPropertiesForm.updateValueAndValidity();
           this.myService.callComponentMethod({isValid:this.contractPropertiesForm.valid})
         }
    })
    this.contractPropertiesForm=this.initFormGroup()
  }

在你的 footer.component 中

  ngOnInit() {
    this.myService.customObservable
      .pipe(filter(x=>x.isValid!=null))
      .subscribe(res=>{
         if (res.isValid)
         {
            if (this.currentStep < this.maxSteps) {
              this.currentStep += 1;
         }
       }
    })
  }

  public onSubmitStep() {
        this.myService.callComponentMethod({command:"check"})
  }

看到按钮调用了一个 callComponentMethod({command:"check"}) 并订阅了 observable。是管理 currentStep 的 observable

表单用“command”监听对象,如果表单有效则发送给callComponentMethod

更新:一个简单的方法如果 form.component 和 footer.component 属于同一个 &lt;router-outlet&gt; (*) 正在使用 Input

如果主要组件是这样的

<app-form #form></app-form>
<app-footer [form]="form"></app-footer>

Out footer 进入一个 Input 的 form.component

@Input('form') form

我们可以简单地

  public onSubmitStep() {
      this.form.contractPropertiesForm.updateValueAndValidity();
      if (this.form.contractPropertiesForm.valid)
          this.currentStep++;
  }

new stackblitz

(*)我想说,如果我们有类似的,这种方法是无效的

<router-outlet></router-outlet>
<app-footer ></app-footer>

【讨论】:

  • 是的!而已!现在它可以工作了:) 我不知道这会如此棘手。非常感谢!
  • @MichałBrzozowski,我觉得自己很愚蠢......有一个简单的方法可以做到这一点。我更新了答案
  • 如果我有路由器插座而不是&lt;app-form #form&gt;&lt;/app-form&gt; 怎么办?简单的方法也能奏效吗?
  • 好吧,如果你有&lt;router-outlet&gt;&lt;/router-outlet&gt;,我知道的唯一方法是第一种方法:使用服务。第二种方法只有当 footer.component 和 form.component 共享相同的ourlet时,我才更正答案以避免混淆
猜你喜欢
  • 2018-10-13
  • 2020-02-05
  • 2019-03-24
  • 1970-01-01
  • 2018-08-07
  • 2021-03-02
  • 1970-01-01
  • 2019-06-23
  • 2019-10-10
相关资源
最近更新 更多