type
status
date
slug
summary
tags
category
icon
password
在 Angular 中使用一些第三方 UI 库的时候,为了满足业务需求,经常会遇到需要通过
ng-template 来传递一些自定义的模板到第三方组件中的情况。比如 ngx-bootstrap 的 Tabs 组件,可以自定义 tab 的模板。今天这篇文章会探究一下背后的原理,并且一步步实现一个类似功能的组件。
Counter 组件
首先创建一个最基本的 Counter 组件。这个组件展示当前的值并且可以执行递增和递减的操作。此外,还可以自定义初始值,并且在值更改时发出事件。
初始代码如下:
html 内容如下:
可配置模板
在 Angular 中,可以借助
ng-template 元素创建视图模板。 生成模板后,可以借助内容投影(content projection)将其传递给可重用组件,最终我们会通过下面的写法来使用组件:通过上面的写法可以看出,每个视图模板都有自己的指令,因此我们可以区分每个
ng-template 属于组件的哪一部分。首先来实现上面的三个指令,每个指令的内容都很简单:只需要公开一个对视图模板的引用。
接下来,我们可以在组件中使用
ContentChild 装饰器获取对视图模板的引用,第一个参数是指令的类名:除了获取模板的
getter 之外,还有一些传递给视图模板的上下文对象的 getter,用来给 ng-template 传递数据。最后在
html 模板中,我们通过 NgTemplateOutlet 指令,将视图模板渲染在组件的适当位置。在大多数第三方 UI 库中,如果没有传递自定义模板,就会使用默认的模板。到这里我们就基本实现了一个可以自定义模板的可重用 Angular 组件。
扩展
ng-template
在上面的实现中,传递给
ng-template 的 context 返回了一个对象:这个对象的
$implicit 属性就是 let-value 对应的变量。我们也可以传递多个对象,比如;其中,
let-value 没有赋值,会被自动赋值为 $implicit 的值。unit 对应返回的上下文对象中的 unit 属性。使用 * Syntax
如果只需要传递一个值到
ng-template,可以使用更简化的语法:string token
在给
ContentChild 装饰器传递第一个参数的时候,也可以传递一个字符串,这个字符串必须是唯一的模板引用变量。结论
在 Angular 中,针对不同的需求场景可以有多种解决方案。如果我们想重用组件的布局,使用这种方式是比较合适的。如果仅仅是想通过内容投影来传递组件,那么使用组件惰性实例化可能是更好的方式。在实际开发中,需要根据不同的场景选择合适的实现。
参考链接:
- Author:大胖猫
- URL:http://preview.tangly1024.com/article/angular-reusable-components
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!









