当前位置: 首页 > 知识库问答 >
问题:

从父组件到动态子组件的角度发射事件

汲永嘉
2023-03-14

编辑:我已经采取了一种不同的方法来解决这个问题:根据接受的答案,在save()上检索父组件中的动态子组件值。

我正在尝试让父组件发出一个Event/Observable,以便它的子动态组件在侦听这样的事件时触发一个动作。

我已经了解到,在动态组件中使用@input()@output()修饰符是不可能的,所以...

这是我用例的大纲:

  1. 动态子组件由一组4个输入元素组成。(完成)
  2. 父组件具有add按钮,用于添加动态子组件。此按钮可用于添加动态子组件的尽可能多的实例。(完成)
  3. 动态子组件具有delete按钮来删除其实例。(完成)
  4. 父组件具有对象数组类型的属性。每个数组项都是一个包含动态组件输入值的对象。(要做)
  5. 父组件有save按钮,单击该按钮时,该按钮将向动态组件实例发出事件,这样每个组件实例都可以将其输入值保存为对象。(即3个实例=>[{A:...,B:...,C:...,D:...},{...},{...}];5个实例=>5个数组项,以此类推)。(要做)

我试图从Save按钮发出父事件(上面的#5),并让动态子组件的每个现有实例监听该事件,然后对父数组执行.push操作(上面的#4)。

这可能不是最佳实践,但还没有设计出任何其他方法来确保在发生了可能不确定的、随机数的添加/删除实例操作之后为现有动态组件实例保存值。

父组件:

HTML

...
<button (click)="addDetailRow()" type="button">Add Detail Row</button>
<div #detailContainer></div>
...
<button (click)="save()">Save</button>
...

打字稿

...
detailRowArray: Array<Object>;
...
addDetailRow() {
    let comp = this._cfr.resolveComponentFactory(DetailRowComponent);
    let detailRowComp = this.container.createComponent(comp);

    detailRowComp.instance._ref = detailRowComp;
    detailRowComp.instance.detailRowArray = this.detailRowArray;
}
save() {
    // TODO: here emit an event/observable
}
...

动态子组件:

HTML

<div><input type="text" name="a" [(ngModel)]="detail_item.a" #a></div>
<div><input type="text" name="b" [(ngModel)]="detail_item.b" #b></div>
<div><input type="text" name="c" [(ngModel)]="detail_item.c" #c></div>
<div>
  <input type="text" name="d" [(ngModel)]="detail_item.d" #d>
  <span>
    <button (click)="removeRow()">Remove Row</button>
  </span>
</div>

打字稿

js prettyprint-override">...
detail_item: { [key: string]: any; } = {};
detailRowArray: Array<Object>;
...
removeRow() {
  ...
}
...
// TODO: trigger this function when parent emits event/observable
saveToParentArray() {
     this.detailRowArray.push(this.detail_item);
}

附注。代码库使用的是模板驱动的表单,所以不可能在其中使用FormArray(我刚刚熟悉angular 2+)。谢谢你的关注。

共有2个答案

翟展
2023-03-14

数据数组可以存在于父组件和子组件中,接受它作为输入并修改它。

理想的情况下(正如在注释中已经提到的),您应该用另一种方法来完成。当用户在子组件中输入数据时,我们可以触发一个从子组件到父组件的事件

但是如果您仍然希望从父级在子组件中执行某些操作,您可以只调用子组件实例并调用它们。

detailRowComp[1].instance.saveToParentArray()

但这是多余的,不是好的做法。从以上两个中选择一个。

巫马英豪
2023-03-14

好吧,我走了一条不同的解析路径:

在对所提供的选项进行了一些研究之后,我不再考虑将事件从父组件实例发送到动态子组件实例;

相反,我抓取了现有的ViewContainerRef变量,并沿着for循环使用它的API检索动态组件实例,然后从该实例检索4个输入元素集,然后以编程方式构造预期的对象,并将其作为项推送到父级的DetailRowarRay数组。问题解决了。

以下是代码的简化版本:

js prettyprint-override">  save() {
    // Temporary variables to construct array of arrays
    let parentNodeArray: any[] = [];
    let inputs: any[] = [];
    // loop to retrieve each existing instance of the dynamic component into temp variable
    for (let i = 0; i < this.container.length; i++) {
      let comp: any;
      comp = this.container.get(i);
      parentNodeArray.push(comp.rootNodes[0]);

    }
    // loop to retrieve values from the set of 4 input elements per instance
    // into temp array var (mixed with good ol' JS)
    parentNodeArray.forEach((elem: any) => {
      inputs.push( Array.prototype.slice.call( elem.querySelectorAll('input') ).map(node => {
        return node.value; });
      );
    });
 类似资料:
  • 我有一个在父组件中生成的事件,子组件必须对此作出反应。我知道在中不建议使用这种方法,我必须执行emit,这非常糟糕。所以我的代码是这个。 正如您所看到的,在无限滚动上被触发,事件被发送到子组件搜索。不仅仅是搜索,因为它是根,所以它正在向每个人广播。 什么是更好的方法。我知道我应该使用道具,但我不知道在这种情况下我该怎么做。

  • 我有两个组件:父组件,我想改变子组件的状态: 和子组件: 我需要从父组件更改子组件的打开状态,或者当单击父组件中的按钮时,从父组件调用子组件的toggleMenu()?

  • 假设我的父组件有两个子组件: 我从Child2获得一个输入,并将其传递给父组件(到目前为止,我知道该怎么做)。但是,我需要将该输入传递给Child1,以更新它的状态。 我怎么能那么做?

  • 子组件事件能否到传递父组件

  • 问题内容: 我正在寻找最简单的解决方案,以将数据从子组件传递给他的父组件。 我听说过使用上下文,传递槽属性或更新道具,但我不知道哪个是最佳解决方案。 我正在建立一个管理界面,其中的一个PageComponent包含一个ChildComponent以及一个可以在其中选择多行的表格。我想向我的父级PageComponent发送我在ChildComponent中选择的行数。 像这样: PageCompo