Angular 2-父母有多个孩子

时间:2017-06-07 05:31:30

标签: angular parent-child

我有一种情况,起初看起来相当直接,但经过几天改变我的解决方案结构后,它变得如此复杂! 好吧,我有一个父/子组件关系如下:

    • 孩子1
      • 孙子1
      • 孙子2
      • 孙子3
    • 孩子2
      • 孙子1
      • 孙子2
      • 孙子3

这些组件(父,子和大孩子)中的每一个都有一个属性为" isValid"和"验证()"方法。我想要实现的是一种解决方案,其中每个组件有效性状态取决于其自己的验证逻辑PLUS所有子组件的有效性。 以下是每个组件的简单验证规则:

  • 如果所有子女和孙子女都有效,则父母isValid = true
  • Child isValid = true如果孩子的数量不超过3且不低于1且所有孩子都有效
  • 孙子isValid =如果其中的文本框具有值
  • ,则为true

我已经阅读了这个https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-on-changes并尝试了它描述的所有可能的方法,但是如果父级别组件的所有子组件都有效,则它们都不符合我的要求!

提前感谢您的建议:)

3 个答案:

答案 0 :(得分:0)

您没有说明the official documentation无法帮助您的原因..

基本上您需要遵循master/detail 指南。

我想我会用几个布尔数组来完成它......

最后说'父母'有一个2的数组,代表它的两个孩子。

所以

parentValid:boolean[]=[false,false];

每个孩子对其孩子都有相同的概念(马克为孙子)

childValid:boolean[]=[false,false,false];

孙子应该只有一个发射器,在有效的变化时通知它的父母。在每个类似的事件上,更新childValid并在那里做你的逻辑(超过3然后少于1 ......)并将结果发送给它的父母。

答案 1 :(得分:0)

在您提及的文档中,您可以使用parent-listens-for-child-event。在每个孩子中,你都会有一个像这样的EventEmitter:

@Output() isValid = new EventEmitter<boolean>();

validate(valid: boolean) {
    this.isValid.emit(valid);
  }

将通过按钮取消验证,例如:

<button (click)="validate(true)">Make child Valid</button>

父绑定一个事件处理程序,它响应子事件有效负载$ event并计算自己的有效性:

children_valid:boolean[]; // for each parent children_valid.length==number_of_children
valid:boolen;
onValidate(valid: boolean, child_number: number) {
   this.children_valid[child_number-1]=valid;
   this.children_valid.some(x=>x==false) ? this.valid=false : this.valid=true
}

// Inside the template of the parent:
<my-child1
  (onValidate)="onValidate($event,1)">
</my-child1>
<my-child2
  (onValidate)="onValidate($event,2)">
</my-child2>
<my-child3
  (onValidate)="onValidate($event,3)">
</my-child3>

如果某个组件是父组件,则它必须在发生更改时发出并接收事件。

答案 2 :(得分:0)

我终于通过服务将绑定组件解决了。在所有验证逻辑位于服务中的方式中,所有父,子和大子验证标志都绑定到该服务。

例如。在大孩子里:

this.subscription = this.validationService.onValidateEvent.subscribe(data => { this.isValid = this.validationService.validate(this.timeOfDay); });