4
  • 我有一个 Angular 8.2 项目,它有两种不同的显示模式(横向|纵向)
  • 在每个内部,顶部和底部都有一个工具栏,围绕着主要内容。
  • menu以及主要是特定于模块的content,因此我正在使用插槽。换句话说:五分之一的不同可能的父组件使用这个组件并提供main内容和一个(个体不同)menu,使用角度内容投影
    <ng-template #menu><ng-content select="[slot='menu']"></ng-content></ng-template>
    <ng-template #content><ng-content select="[slot='content']"></ng-content></ng-template>

    <section *ngIf="landscape">
        <div class="global-ui-top">
            <ng-container *ngTemplateOutlet="menu"></ng-container> // 1st
        </div>
        <some-main-content>
            <ng-container *ngTemplateOutlet="content"></ng-container>
        </some-main-content>
        <div class="global-ui-bottom">
            <ng-container *ngTemplateOutlet="menu"></ng-container> // 2nd
        </div>
    </section>

    // portrait mode
    <section *ngIf="!landscape">
        ... pretty similar to above, also 2× menu, 1× content...

问题:我怎样才能使用一个插槽两次?** 如果我使用例如..不会出现错误

A <ng-container *ngTemplateOutlet="menu"></ng-container> A
B <ng-container *ngTemplateOutlet="menu"></ng-container> B

...但是,插槽 get 仅在最后一次“选择一次”(两个 A 之间的标签仍然为空)。换句话说,我的第一个.global-ui-top仍然是空的。

注意:ng-detour在第 1+2 行有助于解决某个错误。是不会造成伤害,但也没有帮助(遗憾的是ng-template-contents 在“第一次填充”之后不会被冻结)。显然,关于插槽有一个“选择的唯一性”原则。

有没有办法将菜单槽的内容填充到任何类型的模板中,并多次重复使用它(同时都可见)?**

  • 也许是一个花哨的旗帜<ng-content><ng-template?(“静止的”?!?)
  • 或者首先以某种方式将插槽的内容打入@viewChild()(在component.ts中)......
  • 别的...?

小更新

似乎可以将 ng-template 引用捕获到 View Child 中:

   @ViewChild('menu', {static: true}) menuA: TemplateRef<any>;

...aconsole.dir()向我展示了一个有效的 ElementRef,但我无法在 .html-Template 中输出它,即<ng-template [ngTemplateOutlet]="menuA"></ng-template>

4

1 回答 1

5

也许这个谈话会很有用。

我的理解是,ng-content不会创建内容,它只是将内容从一个部分移动到另一个部分。

我认为解决您的问题的方法是使用ng-template. 例如:

投影.component.ts

let instances = 0;

@Component({
  selector: 'app-projected',
template: `projected instance nr: {{ instanceId }}`
})
export class ProjectedComponent implements OnInit {
  instanceId: number;

  constructor() { }

  ngOnInit() {
    this.instanceId = ++instances;
  }

}

父组件.ts

@Component({
  selector: 'app-parent',
  template: `
    <h3>Parent component</h3>

    <p>Using content #1</p>
    <ng-container *ngTemplateOutlet="content"></ng-container>

    <p>Using content #2</p>
    <ng-container *ngTemplateOutlet="content"></ng-container>
  `,
})
export class ParentComponent implements OnInit {
  @ContentChild('content', { read: TemplateRef }) content: TemplateRef<any>;

  constructor() { }

  ngOnInit() {
  }

}

这是重要的事情:

<app-parent>
  <ng-template #content>
    <app-projected></app-projected>
  </ng-template>
</app-parent>

据我了解,里面的东西ng-template可以被认为是一个蓝图。因此,每次使用 时ng-template,都会创建该蓝图的新实例

演示

于 2020-03-28T19:55:08.897 回答