【问题标题】:Angular 9 - use of @ContentChildrenAngular 9 - 使用@ContentChildren
【发布时间】:2020-09-12 00:24:28
【问题描述】:

我有一个 ButtonGroupComponent,我需要在其中渲染两种类型的子项:ButtonActionComponentButtonNavigationComponent

我需要通过@ContentChildren 投射这些孩子,但我能做什么,因为不可能 通过两个选择器?

@ContentChildren(??)
  public children: QueryList<??>;

所以,我尝试了另一种解决方案:我创建了一个组件,GroupableButtonComponent,它由两个(ButtonActionComponentButtonNavigationComponent)扩展。

然后我直接将这个组件传递给 ContentChildren:

@ContentChildren(GroupableButtonComponent)
  public children: QueryList<GroupableButtonComponent>;

但我发现孩子们仍然空虚。

我尝试的另一个解决方案是利用依赖注入并创建一个 GroupableButton 类:

export class GroupableButton {
}

其中ButtonActionComponent

@Component({
      selector: "button-action",
      template: `
        ...
      `,
      providers: [{ provide: GroupableButton, useClass: ButtonActionComponent }],
    })
    export class ButtonActionComponent {
        ...
    }

ButtonNavigationComponent

@Component({
      selector: "button-navigation",
      template: `
        ...
      `,
      providers: [{ provide: GroupableButton, useClass: ButtonNavigationComponent }],
    })
    export class ButtonNavigationComponent {
        ...
    }

我是这样用的:

@ContentChildren(GroupableButton)
  public children: QueryList<GroupableButton>;

但是因为在我的 ButtonGroupComponent 里面我有:

...

this.children
  .toArray()
  .slice(0, visibleButtons)
  .reverse()
  .forEach((button) => {
    const factory = this.factoryResolver.resolveComponentFactory(
      GroupableButton
    );

    const component = this.visibleButtonsContainer.createComponent(
      factory,
      0,
      null,
      [[button.element.nativeElement]]
    );
    this.clonePropertiesFrom(button, component.instance);
    this.buttons.push(component);
  });

...

这一次的问题是我不能将 GroupableButton 作为我的模块中的 entryComponents 传递。

【问题讨论】:

  • 你 100% 过分复杂化了。你能退后一步,在这里谈谈你的实际目标吗

标签: angular typescript


【解决方案1】:

您的解决方案过于复杂。

为什么不简单地通过字符串选择器查询这两个组件:

@ContentChildren('templateRef1, templateRef2') allTypesOfButtons: QueryList<ButtonActionComponent | ButtonNavigationComponent>;

我花时间在stackblitz上举个例子

【讨论】:

  • 她正在遍历元素。使用两个不同的查询列表,她会失去顺序。
  • @0xc14m1z 你在说什么顺序? OP没有提到任何订单
  • 好吧,最后一段代码是一个反向数组上的forEach 语句,因此,我假设如果必须反向循环子列表,我假设需要特定的顺序订单...但也许我错了。 @Elisa 你能告诉我们什么?
  • @0xc14m1z 是的,你说得对,我需要保留按钮的确切顺序,因为我必须将它们放在子菜单中。
  • 如果顺序很重要,您可以为ng-content 中的每个按钮添加模板选择器,并像这样使用它:@ContentChildren('baseButton') children: QueryList&lt;GroupableButtonComponent&gt;; Stackblitz:stackblitz.com/edit/angular-e89usn BTW,我认为这个问题可能与this
【解决方案2】:

首先,不要使用您拥有的提供者,而是这样做:

providers: [{ provide: GroupableButton, useExisting: forwardRef(() => ButtonActionComponent) }],

这将确保您获得正确的组件,并且可以按照您认为合适的方式循环您的组件。

我不确定这是否能解决您的实例化问题,但您是否考虑过组件模板中的旧 ng-content 标签,而不是手动实例化您的组件?

<!-- put this where ever you want to project your buttons.... -->
<ng-content></ng-content>

【讨论】:

    猜你喜欢
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2017-10-11
    • 2021-04-25
    • 2016-11-02
    • 2018-10-20
    • 1970-01-01
    相关资源
    最近更新 更多