Angular 内容投影 content projection 的一个问题的单步调试

举报
Jerry Wang 发表于 2022/10/03 11:19:45 2022/10/03
【摘要】 问题描述我使用如下代码测试一个最简单的 Angular 内容投影场景:import { Component } from '@angular/core';@Component({ selector: 'app-zippy-basic', template: ` <h2>Single-slot content projection</h2> <ng-container></n...

问题描述

我使用如下代码测试一个最简单的 Angular 内容投影场景:

import { Component } from '@angular/core';

@Component({
  selector: 'app-zippy-basic',
  template: `
    <h2>Single-slot content projection</h2>
    <ng-container></ng-container>
  `
})
export class ZippyBasicComponent {}

我期望 app-zippy-basic 的使用者,将传入的 content,投射到元素 ng-container 内部。

消费代码如下图所示:

<app-zippy-basic>
    <p>Is content projection cool?</p>
    <div>ok</div>
</app-zippy-basic>

然而运行时,我在渲染出的页面里,根本看不到 Is content projection cool? 的显示。

问题分析

打开 Chrome 开发者工具,发现 app-zippy-basic 内部只有一个 comment 节点:ng-container

我们在提供内容投影插槽的 Component 的 ng-container 之间随便键入一些字符串,例如 DIV:

渲染后发现,ng-container 没能按照我们期望的工作。

通过查阅 Angular 官网,发现这里把 ng-container 和 ng-content 弄混淆了。此处应该使用 ng-content.

解决方案

ng-content 之间不允许再插入其他元素。仅仅充当一个占位符的角色。

使用 ng-content 之后问题消失。这里我们可以通过单步调试的方式,搞清楚被投影的内容是如何插入到 ng-content 占位符里的。

选择 app-zippy-basic,给其设置一个 dom 断点,类型为 subtree modification

首先执行 template 函数,将 Component 本身的 h2 元素,进行 HTML 源代码的渲染:

接下来是 Angular 处理整个内容投影逻辑的关键:

遇到 ng-content,则调用函数 ɵɵprojection

转而调用 applyProjection

parent node 即是指定义了 ng-content 的 Component 对应的 dom 元素:

rNode 即是被插入到 app-zippy-basic 中的节点,即 app-zippy-basic 的消费者。

消费语法:

<app-zippy-basic>
此处插入你想投影到 app-zippy-basic 内部的 HTML 源代码
</app-zippy-basic>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。