首页 > 解决方案 > 是否打算在 Angular 中评估投影内容,即使它没有呈现给 DOM?

问题描述

我在 Stackblitz 中构建了许多场景,您可以在此处查看:https ://stackblitz.com/edit/angular-zdyy8v

我们特别要解决的问题是场景 B,其中我们将父组件中的内容投影到子组件中:

<app-my-child-b [isShowing]="isShowingB">
    <p>Showing {{ logRenderOf('B') }}</p>
</app-my-child-b>
  public isShowingB = false;

  public logRenderOf (str: string): string {
    console.log(`${str} is rendering`);
    return str;
  }

子组件实际上并没有显示这个内容,因为isShowingBfalse.

这是那个孩子的样子:

<ng-container *ngIf="isShowing">
    <ng-content></ng-content>
</ng-container>
@Input() isShowing = false;

尽管它没有显示此内容,但它仍然呈现该内容,如控制台日志中所示:

B is rendering

这是有道理的,因为我知道它评估<app-my-child-b ...> ... </app-my-child-b>为评论节点,并且父级中没有任何内容说它不应该被渲染。直到它被投射到孩子身上,它才找到一个*ngIf. 孩子甚至不需要使用ng-content,该函数将被调用,无论它被投影到的孩子是什么。

不管是否敏感,这绝对是出乎意料的行为,我怀疑在大多数情况下是不可取的。它似乎也与我们在其他地方看到的非常不一致,在模板等等。例如,这里的场景 D 不会触发控制台日志消息:

<ng-template #myChildD>
    <p>Showing {{ logRenderOf('D') }}</p>
</ng-template>
<app-my-child-d [isShowing]="isShowingD" [template]="myChildD"></app-my-child-d>

感觉场景 B 是一个错误,但它是吗?

(我不确定我是否应该报告它,而且 StackOverflow 有一个更大的社区,所以我想我会先在这里问一下。)

标签: angular

解决方案


在我看来,这是一种预期的行为。

看,当我们在 html 中使用它时

<app-my-child-b [isShowing]="isShowingB">
    <p>Showing {{ logRenderOf('B') }}</p>  <-- literally html code, runs here and whatever happens will be prjected
</app-my-child-b>

它将评估应该投影的内容,因此将在此处“渲染”它并仅投影最终运行该功能的结果。但由于结果在 ngIf 中,因此不会显示。


推荐阅读