Angular 5.x 学习笔记(10)——组件之间的数据交互实
序言
做完 component interaction的实例,不禁有一种小小的心动。 这是因为,在学习与UI相关的技术框架时,我始终坚信,只要掌握以下两点,就算入门了。
(1) 页面的跳转: 技术本质,是路由的管理;
(2)页面之间数据交互: 技术本质,是component 之间的数据交互。
只要是设计UI的APP, 我都会准备这样的一道面试题,给候选人现场编程
从页面A 跳转到页面 B, 在B页面上输入一行字, 返回到页面A, 并在页面A上显示出来。 (本地数据跳转,不需要经过后台)
对一个框架而言,页面之间的数据交互,是多种设计模式的集中表现。Angular 的 component interaction 是如此的简洁优雅。
好了,回到正题,看看它是如何实现的。
component interaction
引入了一个 decorator 概念, 它原本就是一个特殊的标记而已, 如果翻译为中文: “装饰器”,将更加晦涩难懂。 Angular 中常用的 decorator,有 @Component 、 @Input、 @Output。
component 的数据交互,便是通过 @Input 和 @Output 来实现的。
image.png具体来说, 从parent component 传递数据给 child component,需通过 @Input
从设计模式上讲, 从父到子简单。 可以理解为从父视图到子视图;
而从 child component 到 parent component 传递数据,需要通过 @Output 。 从设计模式上讲,子视图把数据传递给父视图,则麻烦一些。需要通过 Event 方式。
具体到我们这个实例,就是 parent component 与 child component之间的数据交互。
实例讲解
场景: 实现下面的页面效果,不是静态页面,而是构建Class 来实现。
传值场景: 从 parent view -> child view。 换句话说, 从父视图到子视图的传值,较为简单, 只需用到 @Input 修饰符即可。
代码示例如下:
image.pngapp.component.ts 文件:
import { Component } from '@angular/core';
import { HEROES } from './hero';
@Component({
selector: 'app-root',
template: `
<h2>{{master}} controls {{heroes.length}} heroes</h2>
<app-child *ngFor="let hero of heroes"
[hero]="hero"
[master]="master">
</app-child>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
heroes = HEROES;
master = 'Master';
}
// 创建数据对象
export class Hero {
name: string;
}
export const HEROES = [
{name: 'Mr. IQ'},
{name: 'Magneta'},
{name: 'Bombasto'}
];
// 在 child.component.ts 文件,添加代码:
import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero'
@Component({
selector: 'app-child',
template: `
<h3>{{hero.name}} says:</h3>
<p>I, {{hero.name}}, am at your service, {{masterName}}.</p>
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() hero: Hero;
@Input('master') masterName: string;
constructor() { }
ngOnInit() {
}
}
需要关注的技术点
(1)创建一个独立的对象, 关键字: classs 的声明
(2)export 关键字,为了供外部component 调用; 类似 C 语言的 extern
(3)注意 [ ] 的使用, 它是插补(interpolation)的意思, 被声明插补的对象,在child 中,可以被 @Input 调用;
(4) {{ obj }} 双向绑定;
(5) (click)绑定一个事件;
(6) alias (别名),比如:
@Input('master') masterName: string;
在父视图中,声明了 [master] = " "; 这个值传到子视图。那怎么使用[master] 对象呢? 可以直接用,比如:
@Input() master
也可以给它一个别名:
@Input('master') masterName: string;
这时,即可直接使用 masterName了
如果不想用别名,怎么办?
// child.component.ts
import { Component, Input } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'app-hero-child',
template: `
<h3>{{hero.name}} says:</h3>
<p>I, {{hero.name}}, am at your service, {{master}}.</p>
`
})
export class HeroChildComponent {
@Input() hero: Hero;
// @Input('master') masterName: string;
@Input() master: string;
}
说明:
@Input() master: string; 这里必须用 master:string; 务必与 app.component.ts 中的 [maser] 完全一致。 说白了,它就是在调用 parent的属性 property)
相应地,在template 中,也要用 , {{master}}
小结
以上讲述了如何从 parent 到 child 传值, 下一篇,讲述如何传值从 child 到 parent。这种场景,我称之为: 逆向传值。 同时会用到 EventEimmitter。