Angular 主从组件
此刻,HeroesComponent
同时显示了英雄列表和所选英雄的详情。
把所有特性都放在同一个组件中,将会使应用“长大”后变得不可维护。 你要把大型组件拆分成小一点的子组件,每个子组件都要集中精力处理某个特定的任务或工作流。
本页面中,你将迈出第一步 —— 把英雄详情移入一个独立的、可复用的 HeroDetailComponent
。
HeroesComponent
将仅仅用来表示英雄列表。 HeroDetailComponent
将用来表示所选英雄的详情。
你可以访问下面的链接 https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail 从 GitHub 上查看我们提供源代码。
制作 HeroDetailComponent
使用 Angular CLI 生成一个名叫 hero-detail
的新组件。
ng generate component hero-detail |
这个命令会做这些事:
- 创建一个目录
src/app/hero-detail
.
在这个目录中会生成四个文件:
- 作为组件样式的 CSS 文件。
- 作为组件模板的 HTML 文件。
- 存放组件类
HeroDetailComponent
的 TypeScript 文件。 HeroDetailComponent
类的测试文件。
该命令还会把 HeroDetailComponent
添加到 src/app/app.module.ts
文件中 @
NgModule 的 declarations 列表中。
编写模板
从 HeroesComponent
模板的底部把表示英雄详情的 HTML 代码剪切粘贴到所生成的 HeroDetailComponent
模板中。
所粘贴的 HTML 引用了 selectedHero
。 新的 HeroDetailComponent
可以展示任意英雄,而不仅仅所选的。因此还要把模板中的所有 selectedHero
替换为 hero
。
完工之后,HeroDetailComponent
的模板应该是这样的:
<div *ngIf= "hero" > <h2>{{hero.name | uppercase}} Details</h2> <div><span>id: </span>{{hero.id}}</div> <div> <label>name: <input [(ngModel)]= "hero.name" placeholder= "name" /> </label> </div> </div> |
添加 @
Input()
hero 属性
HeroDetailComponent
模板中绑定了组件中的 hero
属性,它的类型是 Hero
。
打开 HeroDetailComponent
类文件,并导入 Hero
符号。
import { Hero } from '../hero' ; |
hero
属性必须是一个带有 @Input()
装饰器的输入属性,因为外部的 HeroesComponent
组件将会绑定到它。就像这样:
<app-hero-detail [hero]= "selectedHero" ></app-hero-detail> |
修改 @angular/core
的导入语句,导入 Input 符号。
import { Component, OnInit, Input } from '@angular/core' ; |
添加一个带有 @
Input()
装饰器的 hero
属性。
@Input () hero: Hero; |
这就是你要对HeroDetailComponent
类做的唯一一项修改。 没有其它属性,也没有展示逻辑。这个组件所做的只是通过hero
属性接收一个英雄对象,并显示它。
显示 HeroDetailComponent
HeroesComponent
仍然是主从视图。
在你从模板中剪切走代码之前,它自己负责显示英雄的详情。现在它要把这个职责委托给 HeroDetailComponent
了。
这两个组件将会具有父子关系。 当用户从列表中选择了某个英雄时,父组件 HeroesComponent
将通过把要显示的新英雄发送给子组件 HeroDetailComponent
,来控制子组件。
你不用修改 HeroesComponent
类,但是要修改它的模板。
修改 HeroesComponent
的模板
HeroDetailComponent
的选择器是 'app-hero-detail'
。 把 <app-hero-detail>
添加到 HeroesComponent
模板的底部,以便把英雄详情的视图显示到那里。
把 HeroesComponent.selectedHero
绑定到该元素的 hero
属性,就像这样:
<app-hero-detail [hero]= "selectedHero" ></app-hero-detail> |
[hero]="selectedHero"
是 Angular 的属性绑定语法。
这是一种单向数据绑定。从 HeroesComponent
的 selectedHero
属性绑定到目标元素的 hero
属性,并映射到了 HeroDetailComponent
的 hero
属性。
现在,当用户在列表中点击某个英雄时,selectedHero
就改变了。 当 selectedHero
改变时,属性绑定会修改 HeroDetailComponent
的 hero
属性,HeroDetailComponent
就会显示这个新的英雄。
修改后的 HeroesComponent
的模板是这样的:
<h2>My Heroes</h2> <ul class = "heroes" > <li *ngFor= "let hero of heroes" [ class .selected]= "hero === selectedHero" (click)= "onSelect(hero)" > <span class = "badge" >{{hero.id}}</span> {{hero.name}} </li> </ul> <app-hero-detail [hero]= "selectedHero" ></app-hero-detail> |
浏览器刷新,应用又像以前一样开始工作了。
修改了什么?
像以前一样,一旦用户点击了一个英雄的名字,该英雄的详情就显示在了英雄列表下方。 现在,HeroDetailComponent
负责显示那些详情,而不再是 HeroesComponent
。
把原来的 HeroesComponent
重构成两个组件带来了一些优点,无论是现在还是未来:
- 你通过缩减
HeroesComponent
的职责简化了该组件。 - 你可以把
HeroDetailComponent
改进成一个功能丰富的英雄编辑器,而不用改动父组件HeroesComponent
。 - 你可以改进
HeroesComponent
,而不用改动英雄详情视图。 - 将来你可以在其它组件的模板中重复使用
HeroDetailComponent
。
查看最终代码
你的应用应该变成了这样 在线例子 / 下载范例。本页所提及的代码文件如下:
如果你想直接在 stackblitz 运行本页中的例子,请单击链接:https://stackblitz.com/github/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail
本页中所提及的代码如下:https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail
对应的文件列表和代码链接如下:
文件名
|
源代码
|
---|---|
src/app/hero-detail/hero-detail.component.ts | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/hero-detail/hero-detail.component.ts |
src/app/hero-detail/hero-detail.component.html | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/hero-detail/hero-detail.component.html |
src/app/heroes/heroes.component.html | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/heroes/heroes.component.html |
src/app/app.module.ts | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/app.module.ts |
小结
- 你创建了一个独立的、可复用的
HeroDetailComponent
组件。 - 你用属性绑定语法来让父组件
HeroesComponent
可以控制子组件HeroDetailComponent
。 - 你用
@Input
装饰器来让hero
属性可以在外部的HeroesComponent
中绑定。
https://www.cwiki.us/pages/viewpage.action?pageId=47841998
Angular 主从组件的更多相关文章
- angular学习—组件
组件: vue组件:xxx.vue react组件:xxx.js+xxx.css angular组件:xxx.ts+xxx.css+xxx.html angular的装饰器: @ngModule:an ...
- Angular 父子组件传值
Angular 父子组件传值 @Input @Output @ViewChild 新建一个头部组件 newsheader 在主组件引用 news 组件,在news组件添加 newsheader 组 ...
- Angular 动态组件
Angular 动态组件 实现步骤 Directive HostComponent 动态组件 AdService 配置AppModule 需要了解的概念 Directive 我们需要一个Directi ...
- 2021 年最值得推荐的 7 个 Angular 前端组件库 - DevUI
摘要:DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸.灵活.至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠.取悦眼球的设计.如果你正在开发 ToB 的工 ...
- 后端学 Angular 2 —— 组件间通信
1. 父组件向子组件传递信息 使用@Input 子组件的属性用 @Input 进行修饰,在父组件的模板中绑定变量 例子: import { Component, OnInit, Input } fro ...
- angular smart-table组件如何定制化之初步研究
table表运用在后台管理用得频繁,一般bootstrap的class="table"就能满足样式需求以及分页需求,但是每个产品经理需求不一样,比如说分页:bootstrap分页实 ...
- Angular自定义组件实现数据双向数据绑定
学过Angular的同学都知道,输入框通过[(ngModel)]实现双向数据绑定,那么自定义组件能不能实现双向数据绑定呢?答案是肯定的. Angular中,我们常常需要通过方括号[]和圆括号()实现组 ...
- Angular 向组件传递模板的几种方法
最近在写一个日期选择器组件,为了满足将来可能出现的各种需求,所以需要能够高度的自定义组件的样式.为了达到这个目的,需要能够在日期选择器组件外控制每个日期格子内要显示的内容,比如,标上节假日之类的.这时 ...
- Angular 创建组件
创建组件 0 命令创建 1 创建组件 定义hello.component.ts组件 在app.module.ts中引用并添加到declarations声明中 在app.component.html中使 ...
随机推荐
- Java基础(八)
IO流 概述与分类 Java中的IO流技术主要用于传输数据.典型的应用场景有:读写本地文件,上传下载文件等.按照数据传输的方向可以分为两种: l 输入流(Input):既让数据进入应用程序中. l ...
- 爬取百度贴吧前1000页内容(requests库面向对象思想实现)
此程序以李毅吧为例子,以面向对象的设计思想实现爬取保存网页数据,暂时并未用到并发处理,以后有机会的话会加以改善 首先去百度贴吧分析贴吧地址栏中url后的参数,找到分页对应的参数pn,贴吧名字对应的参数 ...
- 删除链表中重复的结点——牛客剑指offer
题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理 ...
- js特效背景--点线随着鼠标移动而改变
https://blog.csdn.net/css33/article/details/89450852 https://www.cnblogs.com/qq597585136/p/7019755.h ...
- Hyperledger Fabric 环境搭建(2)
上一篇https://www.cnblogs.com/xdyixia/p/11738096.html 介绍了Hyperledger Fabric环境中各种软件安装和源码编译,这一篇介绍快速运行一个简单 ...
- hive各种报错
搭建了 CDH6.1.0环境 新加入一台机器都hive但是报错 javax.jdo.JDODataStoreException: Required table missing : "`VER ...
- 安卓端调用h5界面js方法和ios端调用h5界面js方法
备注:本人为h5开发人员,不懂安卓和ios,这是开发小伙伴对接联调的主代码. 1.iOS端调用h5界面js方法: 2.安卓端调用h5界面js方法: @Override protect ...
- 微信小程序多video播放暂停问题
<swiper class="swiper" indicator-dots="{{indicatorDots}}" autoplay="{{fl ...
- scrapy常用设置和注意点!!!!
setting里的设置 HTTPERROR_ALLOWED_CODES = [405] //这一条是忽略405错误退出进程,有可能跳到405页面,在parse注意判断,重新请求页面 爬虫里的设置 ...
- 第十篇.2、python并发编程之多进程
一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.P ...