父子组件之间的交互

2017-07-05  本文已影响25人  JamesSawyer

问题: 一个组件什么时候放在另一个组件内?

比如我有一个 Content 组件,它有2个子组件 ListPlayer。点击一个 List 元素将加载一个视频到 Player 中。那么问题来了,是否 Player 组件是否应当放在 List 组件当中,他们之间是如何进行交互的?

答案

有一个被大家都接受的架构模式称之为 智能组件和呈现组件(smart component && dumb component).

简而言之,就本问题来讲, ContentComponent 组件将是一个智能组件,它将状态和属性传递给它的子组件,即将 videos 传递给 ListComponent, 将 chosenVideo(选中的那个视频)传递给 PlayerComponent 组件。我们可以在 ListComponent 组件中通过自定义事件(emit an Event) 来更新 PlayComponent 中播放的视频

下面代码示例:

// ContentComponent 父组件
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
@Component({
  selector: 'my-content',
  template: `
    <my-list [list]="list | async" (onChosenVideo)="setVideo($event)"></my-list>
    <my-player [video]="chosenVideo"></my-player>
  `
})
export class ContentComponent implements OnInit {
  // 这个组件用于接收外界状态,即从某个视频服务哪里获取所有的videos
  list: Observable<Video[]>;

  // 这个属性表示被选中的那个视频
  chosenVideo: Video;

  constructor(
    private videoService: SomeVideoService // 注入该视频服务
  ) {}

  ngOnInit() {
   // 获取video lists
    this.list = this.videoService.getVideosFromSomeAPISomewhere();
  }

  // 父组件的方法 设置选中的组件
  setVideo(video: Video) {
    this.chosenVideo = video;
  }
}

// 子组件
// ListComponent
@Component({
  selector: 'my-list',
  template: `
    <ul *ngFor="let video of videos">
      <li (click)="setVideo(video)"> {{ video.title}}</li>
    </ul>
  `
})
export class ListComponent {
  // ListComponent 不关心视频数组从哪里来,它只获取数据即可,即将属性从别处输入到这个组件(Input)
  // 这可以认为是组件API的一部分
  // 当别人要使用ListComponent组件时,他的责任就是坚持上面的原则
  @Input list: Video[];

  // 当使用ListComponent组件时, ListComponent向外输出一个事件,
  // 这也是ListComponent组件API的一部分

  // 相当于自定义事件, 和父组件进行交互
 @Output() onChoseVideo: EventEmitter = new EventEmitter();

  setVideo(video: Video) {
    this.onChoseVideo.emit(video); // 向外传递这个这个值
  }
}

// PlayerComponent
@Component({
  selector: 'my-player',
  template: `
    <div id="player"><!-- your video player html element here --></div>
  `
})
export class PlayerComponent {
  // 这个组件只关心输入进来的Video,它不关心视频从哪里来
  @Input video: Video;
}

export class Video {
  title: string;
  id: string;
  description: string
}

这篇文章来自 reddit angular2 讨论区, 这对父子组件之间的交互讲解的十分的透彻,值得反复的看。

相关文章:
另外这篇文章讲解得很清楚:

上一篇 下一篇

猜你喜欢

热点阅读