【问题标题】:Angular 2- Parent with multiple childrenAngular 2-有多个孩子的父母
【发布时间】:2017-06-25 00:10:20
【问题描述】:

我有一种情况,起初对自己来说似乎相当直截了当,但在改变我的解决方案结构几天后,它变得如此复杂! 那么我有一个父/子组件关系如下:

  • 父母
    • 儿童 1
      • 孙子 1
      • 孙子2
      • 孙子 3
    • 孩子 2
      • 孙子 1
      • 孙子2
      • 孙子 3

这些组件中的每一个(父、子和孙子)都有一个“isValid”属性和一个“validate()”方法。我想要实现的只是一个解决方案,其中每个组件的有效性状态都取决于它自己的验证逻辑以及所有子组件的有效性。 下面是每个组件的简单验证规则:

  • 如果所有子孙都有效,则父 isValid = true
  • Child isValid = true 如果其子代数不超过 3 且不小于 1 加上所有子代都有效
  • grandchild isValid = true 如果其中的文本框有值

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

提前感谢您的建议:)

【问题讨论】:

  • 更多细节在这里:link

标签: angular parent-child


【解决方案1】:

我终于通过服务将组件绑定在一起解决了这个问题。所有验证逻辑都位于服务中,所有父、子和孙验证标志都绑定到该服务。

例如。在孙子中:

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

【讨论】:

    【解决方案2】:

    你没有说明为什么 the official documentation 没有帮助你..

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

    我想我会用几个布尔数组来做到这一点......

    最后说“父母”有一个 2 的数组,表示它是两个孩子。

    所以

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

    每个孩子对自己的孩子都有相同的概念(标记为孙子)

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

    孙子应该只有一个发射器女巫通知它的父母有效的变化。在这样的每个事件上,更新childValid 并在那里执行您的逻辑(多于 3 或少于 1...)并将结果发送给它的父级。

    【讨论】:

      【解决方案3】:

      在您提到的文档中,您可以使用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>
      

      如果一个组件是父子,它必须在发生变化时发出和接收事件。

      【讨论】:

      • 感谢您非常详细的回复。我已经根据您的提示找到了一个解决方案,但仍然有几个奇迹:1)当每个孩子加载时,我需要在其父级中调用 validate 函数来查看孩子是否有效,因为有一个按钮绑定到子 isValid 属性,如果子无效,则应禁用。我应该在哪里/何时调用验证函数?!
      • 这似乎是一个生命周期钩子案例,尤其是一个 ngOnInit:link。您创建了一个钩子并将其绑定到按钮上,例如:&lt;button (click)="validate(true) [disabled]="!valid""&gt;Make child Valid&lt;/button&gt;。我提供的验证功能在孩子中,所以如果我能看到你必须更好地理解问题的代码会更好。如果问题仍然存在,请接受此答案并打开一个新的详细问题。
      • 我刚刚尝试了您的解决方案,但问题是我没有父子组件上的按钮来运行从孙子向上的验证周期。唯一的按钮位于会触发验证周期的孙子上。因此,在设置所有内部孙子的有效性之前,不能设置更高级别组件(父母和孩子)的有效性。因此,在填充所有对等节点之前,孙子节点无法触发其父节点验证功能。
      • 由于您在孙子中有一个按钮,因此孙子必须按照答案中的描述向其所属的孩子发出任何更改。然后孩子必须作为孙子的父母(使用 eventHandler)接收该值,同时在计算后将其状态更改发送给整个父母。父级将处理来自其子级的这些事件并计算其状态。
      猜你喜欢
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      相关资源
      最近更新 更多