问题描述

我创建了一个 selector 为 app-content-section 的 Component,用于容纳内容投影(content projection):

这个 Component 的模板区域,分别定义了三个 div 区域,里面包含了对应的内容投影占位符 ng-content:

第一个绿色区域接收所有 div 标签,第二个蓝色区域接收所有包含了 css class content-class 的标签,第三个区域接收所有 name 属性值为 test 的标签。

我们来看看消费这个 Component 的代码:

<app-content-section><div name="test">div[name="test"]</div><div>纯粹的 div 标签</div><p #six class="content-class">p 标签,包含 [class="content-class] 和 six id</p><p name="test">p 标签 [name="test"]</p>
</app-content-section>
  • app-content-section 中包含两个 div 元素,故最后的绿色区域里,包含了两个 div 值:

蓝色区域内只显示了一个 p 标签,因为这是消费者传入的元素里,唯一一个带有 content-class 类的元素。

接下来的问题是,消费者传入的元素里,第一个 div 元素和最后一个 p 元素的 name 属性值都为 test,为什么只有最后一个 p 标签,被投影到 app-content-section 里呢?

问题分析

第一个 div 标签同时满足第一条和第三条内容投影规则,因此其被投影到第一个 ng-content 之后,就不会再重复被投影了。

我们可以做一个测试,把提供内容投影场所的 Component 内的第一个和第三个 ng-content 调换一下顺序:

这次的测试结果,红色区域出现的两个元素,其 name 属性值都为 test. 而虽然绿色区域容纳的是被投射的 div 元素,但是因为 name = test 的 div 元素,已经被优先投射到红色区域,所以它不会再被重复投射了。

总结

通过单步调试 Angular content projection 的相关代码,也能确认上述逻辑。

当 Component 的模板文件被解析,遇到 ng-content 时:

触发 ɵɵprojection 函数。

applyProjectionRecursive 函数里的 nodeToProject,就是需要被投影的 DOM 节点:

可以看到这里只有包含了 name = test 属性值的 div 被 Angular 框架解析成需要被投影的节点。

通过单步调试的方式学习 Angular 中带有选择器的内容投影使用方式相关推荐

  1. 通过单步调试的方式学习 Angular 中 TView 和 LView 的概念

    问题描述 本文涉及到的代码位置:https://github.com/wangzixi-diablo/ngDynamic 看这样一组 parent Component 和 child Componen ...

  2. 草根方式学习java中的多线程

    草根方式学习java中的多线程 下面有具体的代码和截图 源码点这里 多线程即在同一时间,可以做多件事情(说白了,就是齐头并进) 单线程就是按部就班 创建多线程有2种方式,分别是继承线程Thread类, ...

  3. 用类比方式学习编程中函数递归(个人理解仅供参考)(内含汉诺塔问题的求解)

    目录 1.前言 2.递归的数学模型 3.相关的c语法 4.将递归的数学模型写成编程语言 5.利用类比方法将实际问题的代码写成函数递归的形式 例1: 例2: 6.汉诺塔问题的求解 1.前言 本人在学习函 ...

  4. Angular 基于自定义指令的内容投影 content projection 问题的单步调试

    问题描述 本文涉及到的代码位置:https://github.com/wangzixi-diablo/ngDynamic 我有一个能接受内容投影的 Angular Component: 具体投影内容, ...

  5. mysql修改表名几种方式_Oracle数据库中修改表名的几种方式

    Oracle数据库中修改表名的几种方式如下:answer1: ALTER TABLE old_table_name RENAME TO new_table_name;(大写为系统命令)answer2: ...

  6. java中读取properties文件内容五种方式

    一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ...

  7. php中用户验证的方式,在php中进行用户身份验证的最佳方式是什么?

    使用 Sessions.将会话ID存储在cookie中,并将用户的状态存储在服务器端(loggedIn,userId,IP). 澄清您需要存储在会话数组中: > loggedIn:一个关于用户是 ...

  8. Vue+element ui 表格中时间选择器范围控制(两种方式)

    1.页面 <el-table v-loading="loading" :data="tableList" border> <!-- 方法1 - ...

  9. 获取Angular中的AngularJS功能

    介绍 ( Introduction ) If you have solid experience with AngularJS 1.x, you're well aware of the framew ...

最新文章

  1. YOLOv5在最新OpenVINO 2021R02版本的部署与代码演示详解
  2. css文本换行_CSS样式更改——文本Content
  3. 从Wiesloch火车站到SAP Walldorf总部的交通方式
  4. vue 组件 props配置
  5. 深入理解DDD中的聚合
  6. 老外看中国:本土移动应用差异在哪?
  7. viewport meta 标签在手机浏览器上控制布局
  8. ubuntu使用python_Ubuntu+Python环境配置(III)—用Python
  9. 监听屏幕解锁和判断屏幕状态
  10. python opencv3 —— 常用工具、辅助函数、绘图函数(图像添加文本、矩形等几何形状)
  11. 模板类成员函数特例化写法
  12. JAVA 汉字转化中文拼音
  13. cp105b linux 驱动,富士施乐 DocuPrint CP105b驱动
  14. 从完美KL距离推导VAE
  15. 【懒懒】我不生产笑话,我只是笑话的搬运工 [问题点数:200分]
  16. 手机识别图片文字的方法
  17. 【人话版】分布式数字身份:通往WEB3世界的桥头堡
  18. 谁知道下面这个视频中的特效是用什么软件做的?
  19. 如何做好软文推广?软文推广有哪些宣传平台值得推荐
  20. Cisco Packet Tracer中配置三层交换机

热门文章

  1. 什么是反射和字节码对象。
  2. 一起学shell之(九-2)拼写检查、进程
  3. maven的dependency 和 dependencymanagement
  4. JavaScript强化教程 —— JavaScript 总结
  5. Android官方导航栏ActionBar(二)—— Action View、Action Provider、Navigation Tabs的详细用法...
  6. ahjesus 创建msdn一样的帮助文档
  7. Java数据解析---PULL
  8. Android--生命周期【转】
  9. 快速安装LNMP环境
  10. jQuery中操作元素节点appendTo()与prependTo()的区别