美文网首页
父子组件之间的交互

父子组件之间的交互

作者: JamesSawyer | 来源:发表于2017-07-05 23:31 被阅读25次

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

    比如我有一个 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 讨论区, 这对父子组件之间的交互讲解的十分的透彻,值得反复的看。

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

    相关文章

      网友评论

          本文标题:父子组件之间的交互

          本文链接:https://www.haomeiwen.com/subject/idjchxtx.html