如何在Angular应用中创建包含组件方法示例


Posted in Javascript onMarch 23, 2019

理解组件包含

包含组件就是指可以包含其它组件的组件, 以 Bootstrap 的卡片 (Card) 为例, 它包含页眉 (header) 、 主体 (body) 和 页脚 (footer) , 如下图所示:

如何在Angular应用中创建包含组件方法示例

<div class="card text-center">
 <div class="card-header">
 Featured
 </div>
 <div class="card-body">
 <h5 class="card-title">Special title treatment</h5>
 <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">Go somewhere</a>
 </div>
 <div class="card-footer text-muted">
 2 days ago
 </div>
</div>

那么问题来了, 如何用 angular 来实现这样的一个组件?

  • 卡片的页眉和页脚只能显示文本;
  • 卡片的主体能够显示任意内容, 也可以是其它组件;

这就是所谓的包含。

创建包含组件

在 angular 中, 所谓的包含就是在定义固定视图模板的同时, 通过 <ng-content> 标签来定义一个可以放动态内容的位置。 下面就来实现一个简单的卡片组件。

卡片组件的类定义为:

// card.component.ts
import { Component, Input, Output } from '@angular/core';

@Component({
 selector: 'app-card',
 templateUrl: 'card.component.html',
})
export class CardComponent {
 @Input() header: string = 'this is header'; 
 @Input() footer: string = 'this is footer';
}

@Input 是一个声明, 允许从父组件传入任意的文本。

卡片组件的的视图模板定义为:

<!-- card.component.html -->
<div class="card">
 <div class="card-header">
 
 </div>
 <div class="card-body">
 <!-- single slot transclusion here -->
 <ng-content></ng-content>
 </div>
 <div class="card-footer">
 
 </div>
</div>

为了能够在其它组件中使用, 需要在对应的 AppModule 中添加声明:

import { NgModule }  from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { CardComponent } from './card.component'; // import card component

@NgModule({
 imports:  [ BrowserModule ],
 declarations: [ AppComponent, CardComponent ], // add in declaration
 bootstrap: [ AppComponent ],
})
export class AppModule { }

如果使用了 angular-cli 来生成这个组件的话, 会自动在 AppModule 中添加声明。

使用卡片组件

在另外一个组件 AppComponent 中使用刚刚创建的卡片组件的话, 代码如下所示:

<!-- app.component.html -->
<h1>Single slot transclusion</h1>
<app-card header="my header" footer="my footer">
 <!-- put your dynamic content here -->
 <div class="card-block">
 <h4 class="card-title">You can put any content here</h4>
 <p class="card-text">For example this line of text and</p>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">This button</a>
 </div>
 <!-- end dynamic content -->
<app-card>

当然, 可以使用 [header] 以及 [footer] 进行数据绑定。

选择符

<ng-content> 接受一个 select 属性, 允许定义选择符, 可以更加精确选择被包含的内容。 打开 card.component.html , 做一些修改

<!-- card.component.html -->
<div class="card">
 <div class="card-header">
 
 </div>
 <!-- add the select attribute to ng-content -->
 <ng-content select="[card-body]"></ng-content>
 <div class="card-footer">
 
 </div>
</div>

注意, 添加了 select="[card-body]" , 这意味着将被包涵的元素必须有 card-body 属性, 用法也需要响应的调整一下

<!-- app.component.html -->
<h1>Single slot transclusion</h1>
<app-card header="my header" footer="my footer">
 <!-- put your dynamic content here -->
 <div class="card-block" card-body><!-- We add the card-body attribute here -->
 <h4 class="card-title">You can put any content here</h4>
 <p class="card-text">For example this line of text and</p>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">This button</a>
 </div>
 <!-- end dynamic content -->
<app-card>

<ng-content> 的 select 属性接受标准的 css 选择符, 比如: select="[card-type=body]" select=".card-body" select="card-body" 等等。

包含多个位置

使用 select 属性, 可以在一个组件中定义多个包含位置。 现在继续修改卡片组件, 允许页眉和页脚包含动态内容。

<!-- card.component.html -->
<div class="card">
 <div class="card-header">
 <!-- header slot here -->
 <ng-content select="[card-header]"></ng-content>
 </div>
 <!-- add the select attribute to ng-content -->
 <ng-content select="[card-body]"></ng-content>
 <div class="card-footer">
 <!-- footer slot here -->
 <ng-content select="[card-footer]"></ng-content>
 </div>
</div>

用法也相应的修改一下:

<!-- app.component.html -->
<h1>Single slot transclusion</h1>
<app-card>
 <!-- header -->
 <span card-header>New <strong>header</strong></span>
 <!-- body -->
 <div class="card-block" card-body>
 <h4 class="card-title">You can put any content here</h4>
 <p class="card-text">For example this line of text and</p>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">This button</a>
 </div>
 <!-- footer -->
 <span card-footer>New <strong>footer</strong></span>
<app-card>

小结

使用包含组件, 可以将布局提取成组件, 动态指定加载的内容, 应该也是很常用的。 而至于选择符 (select), 则建议使用属性, 这样可读性比较好, 也不会破坏 html 的结构。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
这段js代码得节约你多少时间
Dec 20 Javascript
基于IE下ul li 互相嵌套时的bug,排查,解决过程以及心得介绍
May 07 Javascript
JS文本框追加多个下拉框的值的简单实例
Jul 12 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
Jan 03 Javascript
在css加载完毕后自动判断页面是否加入css或js文件
Sep 10 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
自己编写的支持Ajax验证的JS表单验证插件
May 15 Javascript
JavaScript事件代理和委托详解
Apr 08 Javascript
JS将unicode码转中文方法
May 08 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
Sep 12 Javascript
vue2.0 + ele的循环表单及验证字段方法
Sep 18 Javascript
js实现全选和全不选
Jul 28 Javascript
vue中组件的3种使用方式详解
Mar 23 #Javascript
ES6入门教程之Array.from()方法
Mar 23 #Javascript
setTimeout与setInterval的区别浅析
Mar 23 #Javascript
如何通过setTimeout理解JS运行机制详解
Mar 23 #Javascript
vue中axios请求的封装实例代码
Mar 23 #Javascript
vueScroll实现移动端下拉刷新、上拉加载
Mar 22 #Javascript
浅谈Angular单元测试总结
Mar 22 #Javascript
You might like
索尼SONY ICF-SW7600GR电路分析与改良
2021/03/02 无线电
php adodb介绍
2009/03/19 PHP
php 使用post,get的一种简洁方式
2010/04/25 PHP
php检测文件编码的方法示例
2014/04/25 PHP
PHP 使用redis简单示例分享
2015/03/05 PHP
php简单图像创建入门实例
2015/06/10 PHP
js清除input中type等于file的值域(示例代码)
2013/12/24 Javascript
编程语言JavaScript简介
2014/10/16 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
2015/11/02 Javascript
Bootstrap轮播加上css3动画,炫酷到底!
2015/12/22 Javascript
Bootstrap插件全集
2016/07/18 Javascript
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
2018/01/09 Javascript
react-navigation之动态修改title的内容
2018/09/26 Javascript
[01:45]DOTA2新英雄“神谕者”全方位展示
2014/11/21 DOTA
python getopt 参数处理小示例
2009/06/09 Python
Python查看多台服务器进程的脚本分享
2014/06/11 Python
Python3实现将文件归档到zip文件及从zip文件中读取数据的方法
2015/05/22 Python
Python写入数据到MP3文件中的方法
2015/07/10 Python
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
CentOS 7 安装python3.7.1的方法及注意事项
2018/11/01 Python
python去除拼音声调字母,替换为字母的方法
2018/11/28 Python
利用Python求阴影部分的面积实例代码
2018/12/05 Python
python tkinter实现屏保程序
2019/07/30 Python
Tensorflow获取张量Tensor的具体维数实例
2020/01/19 Python
美国折扣地毯销售网站:Rugs.com
2020/03/27 全球购物
serialVersionUID具有什么样的特征
2014/02/20 面试题
什么叫应用程序域?什么是托管代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
2012/05/23 面试题
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
机关副主任个人四风问题整改措施
2014/09/26 职场文书
思想纪律作风整顿剖析材料
2014/10/11 职场文书
社区五一劳动节活动总结
2015/02/09 职场文书
乡镇科协工作总结2015
2015/05/19 职场文书
公司周年庆寄语
2019/06/21 职场文书
Python实现简单的俄罗斯方块游戏
2021/09/25 Python
解决vue-router的beforeRouteUpdate不能触发
2022/04/14 Vue.js