Angular:访问使用 ngTemplateOutlet 渲染的递归列表中的父指令

问题描述 投票:0回答:1

我正在使用模板来显示嵌套列表,如下所示:

const tree = [
  { label: "A" },
  { label: "B" },
  {
    label: "C",
    children: [
      { label: "C0" },
      { label: "C1" },
      { label: "C2" },
    ],
  },
  { label: "D" },
  { label: "E" },
  {
    label: "F",
    children: [
      { label: "F0" },
      {
        label: "F1",
        children: [
          { label: "F1-0" },
          {
            label: "F1-1",
            children: [
              { label: "F1-1-0" },
              { label: "F1-1-1" },
              { label: "F1-1-2" },
            ],
          },
          { label: "F1-2" },
        ],
      },
      { label: "F2" },
    ],
  },
];

这是我的 HTML 模板:

<ul>
  <ng-template #itemTemplate let-entry>
    <li myDirective>{{ entry.label }}
      <ng-container *ngIf="entry.children && entry.children.length">
        <ul>
          <ng-container *ngFor="let child of entry.children">
            <ng-template *ngTemplateOutlet="itemTemplate; context: { $implicit: child }"></ng-template>
          </ng-container>
        </ul>
      </ng-container>
    </li>
  </ng-template>

  <ng-container *ngFor="let item of tree">
    <ng-template *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-template>
  </ng-container>
</ul>

我的目标是从子

myDirective
实例中检索父
myDirective
实例。在
myDirective
的构造函数中,我尝试使用:

@Optional() @SkipSelf() private parentItem?: MyDirective | null;

这仅在显式渲染树而不使用模板时才有效。否则,依赖层次结构似乎会丢失。

所以,我的问题是:如何从通过模板呈现的子元素中获取对父元素的指令实例的引用?

例如,如何从

"F1-1"
的指令实例中访问
"F1-1-0"
的指令实例?

angular dependency-injection
1个回答
0
投票

我的解决方案不涉及依赖注入,而是通过

ng-template
ng-container
传递引用,我们使用指令的
exportAs
属性来获取组件范围并设置为
templateReferenceVariable
(
directiveScope
) 和传递给
that

@Directive({
  selector: '[myDirective]',
  exportAs: 'myDirective',
})
export class MyDirective {
  ...
}

我们将

this
作为名为
that
的属性传递到上下文中。

<ul>
  <ng-template #itemTemplate let-entry let-that="that">
    <li myDirective #directiveScope="myDirective">{{ entry.label }}
      <ng-container *ngIf="entry.children && entry.children.length">
        <ul>
          <ng-container *ngFor="let child of entry.children">
            <ng-template *ngTemplateOutlet="itemTemplate; context: { $implicit: child, that: directiveScope }"></ng-template>
          </ng-container>
        </ul>
      </ng-container>
    </li>
  </ng-template>

  <ng-container *ngFor="let item of tree">
    <ng-template *ngTemplateOutlet="itemTemplate; context: { $implicit: item, that: null }"></ng-template>
  </ng-container>
</ul>
© www.soinside.com 2019 - 2024. All rights reserved.