WEB全栈技术产品经理我爱编程

Angular 5.x 学习笔记(10)——组件之间的数据交互实

2018-04-03  本文已影响151人  全栈开发之道

序言

做完 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.png

app.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。

上一篇 下一篇

猜你喜欢

热点阅读