美文网首页
angular组件交互

angular组件交互

作者: 我不傻_cyy | 来源:发表于2019-01-17 17:07 被阅读0次
1.父组件通过属性绑定的方式将数组从上到下的流入到子组件中,子组件需要通过@Input装饰器来获取。

例如:

父组件为
@Component({
      template: `
          <ul class="list">
                 <li *ngFor="let contact of contacts">
                        <app-list-item [contact]="contact"></app-list-item>
                 </li>
          </ul>
`
})
export class ListComponent implement OnInit{
          this.contacts = data;
}
子组件为:
@Component({
        template:`
             <div class="contact-info">
                  <label class="contact-name">{{contact.name}}</label>
                  <label class="contact-tel">{{contact.telNum}}</label>
            </div>        
`
})
export class ListItemComponent implements OnInit{
      @Input() contact: any = {};
}
2.子组件通过事件传递的方式向父组件传递数据,子组件需要实例化EventEmitter类,并使用装饰器@Output修饰这个输出属性。父组件通过事件绑定的方式来订阅来自子组件触发的事件。
父组件:
@Component({
        template: `
            <contact-collect [contact]="detail" (onCollect)="collectTheContact($event)"></contact-collect>
        `
})
export class CollectionComponent implements OnInit{
        detail: any = {};
        collectTheContact(){
              this.detail.collection == 0 ? this.detail.collection = 1 : this.detail.collection = 0;  
      }
}
父组件通过绑定自定义事件onCollect订阅来自子组件触发的事件。
子组件
@Component({
      template: `<i  (click)=collectionTheContact()>收藏</i>`
})
export class ContactCollectComponent{
      @Input() contact: any = {};
      @Output() onCollect = new EventEmitter<bollean>();
      collectTheContact(){
          this.onCollect.emit();
      }
}

通过@Output将数据流向父组件。

3.父组件通过局部变量获取子组件的引用、父组件使用@ViewChild获取子组件的引用

(1)在父组件的模板中为子组件创建一个局部变量,就可以在父组件的模板中访问子组件的所有属性和方法。这个局部变量有局限性,因为模板变量只能在模板中使用,父组件的类不能使用这个局部变量访问子组件的属性和方法。
例如

父组件:
@Component({
      template:`
            <contact-collect (click)="collect.collectTheContact()" #collect></contact-collect>
      `
})
export class CollectionComponent{}
在父组件中为子组件创建了一个局部变量#collect,父组件就可以使用#collect调用子组件的方法collectTheContact()
子组件
@Component({
        template:<i>收藏</i>
})
export class ContactCollectComponent{
      detail: any = {};
      collectTheContact(){
          this.detail.collection == 0 ? this.detail.collection = 1 : this.detail.collection = 0;
      }
}

(2)使用@ViewChid属性装饰器获取子组件的引用,该方法获取的引用可以在父组件类中使用。
@ViewChild()提供了一个参数来选择将要引用的组件元素。这个参数可以是一个类的实例,也可以是字符串。
I.参数为类实例,表示父组件将绑定一个指令或者子组件实例
II.参数为字符串类型,相当于在父组件中绑定一个模板局部变量,获取到子组件的一个实例对象的引用。

参数为字符串
@ViewChild("dateRange")
private dateRange: OpsDateRangeComponent;
<ops-date-range #dateRange style="line-height: 29px"
                            (changeDateEvent)="dateListener($event)"></ops-date-range>
参数为类实例
@Component({
      template:`
            <contact-collect (click)="collectTheContact()"></contact-collect>
`
})
export class CollectionComponent{
      @ViewChild(ContactCollectComponent) contactCollect: ContactCollectComponent;
      ngAfterViewInit(){}
      collectTheContact(){
            this.contactCollect.collectTheContact();
      }
}
组件内容嵌入

<ng-content>标签用来渲染组件嵌入内容。
例如:

@Component({
    selector: 'example-content'
    template: `
        <div>
            <h4>ng-content实例</h4>
            <div style="background-color: gray">
                <ng-content select="header"></ng-content>
            </div>
       </div>
`
})
class NgContentExampleComponent{}
<ng-content>中有一个select="header",用于匹配内容。并填充到ng-content中。
使用
@Component({
      selector:'app'
      template:`
          <example-content>
                <header>Header content</header>
          </exampe-content>
`
})
export class NgContentAppComponent{}
最后渲染成的是
<app>
    <example-content>
        <div>
            <h4>ng-content</h4>
            <div style="background-color: gray">
                <header>Header content</header>
            </div>
        </div>
       </example-content>
</app>
从图中可以看出<header>Header content</header>被填充到了ng-content,select属性是一个选择器,类似于css的选择器,可以有标签选择器、类选择器、属性选择器。

4.通过setter监听输入属性值的变化
使用一个输入属性的setter,来拦截父组件中值的变化,并采取行动。

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-name-child',
  template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
  private _name = '';

  @Input()
  set name(name: string) {
    this._name = (name && name.trim()) || '<no name set>';
  }

  get name(): string { return this._name; }
}
在组件Namechildcomponent的输入属性name上设置了setter,会将父组件传回来的name去掉空格,或者将空值替换成默认的字符串。

5.通过ngOnChanges()来监听输入属性值的变化
使用OnChanges声明周期钩子接口的ngOnChanges()方法来监测输入属性值的变化并做出回应。(相比于setter方式,该方式可以舰艇多个输入属性)

import { Component, Input, OnChanges, SimpleChange } from '@angular/core';

@Component({
  selector: 'app-version-child',
  template: `
    <h3>Version {{major}}.{{minor}}</h3>
    <h4>Change log:</h4>
    <ul>
      <li *ngFor="let change of changeLog">{{change}}</li>
    </ul>
  `
})
export class VersionChildComponent implements OnChanges {
  @Input() major: number;
  @Input() minor: number;
  changeLog: string[] = [];

  ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
    let log: string[] = [];
    for (let propName in changes) {
      let changedProp = changes[propName];
      let to = JSON.stringify(changedProp.currentValue);
      if (changedProp.isFirstChange()) {
        log.push(`Initial value of ${propName} set to ${to}`);
      } else {
        let from = JSON.stringify(changedProp.previousValue);
        log.push(`${propName} changed from ${from} to ${to}`);
      }
    }
    this.changeLog.push(log.join(', '));
  }
}
这个VersionChildComponent 组件会监测major和minor属性的变化,并把这些变化写成日志报告出来。
VersionChildComponent 提供minor和major值,把修改它们值的方法绑定到按钮上。
import { Component } from '@angular/core';

@Component({
  selector: 'app-version-parent',
  template: `
    <h2>Source code version</h2>
    <button (click)="newMinor()">New minor version</button>
    <button (click)="newMajor()">New major version</button>
    <app-version-child [major]="major" [minor]="minor"></app-version-child>
  `
})
export class VersionParentComponent {
  major = 1;
  minor = 23;

  newMinor() {
    this.minor++;
  }

  newMajor() {
    this.major++;
    this.minor = 0;
  }
}

父组件和子组件通过服务来进行通讯
父组件和子组件共享同一个服务,利用该服务在组件家族中实现双向通讯。
例如:
服务:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs';

@Injectable()
export class MissionService {

  // Observable string sources
  private missionAnnouncedSource = new Subject<string>();
  private missionConfirmedSource = new Subject<string>();

  // Observable string streams
  missionAnnounced$ = this.missionAnnouncedSource.asObservable();
  missionConfirmed$ = this.missionConfirmedSource.asObservable();

  // Service message commands
  announceMission(mission: string) {
    this.missionAnnouncedSource.next(mission);
  }

  confirmMission(astronaut: string) {
    this.missionConfirmedSource.next(astronaut);
  }
}

MissionControlComponent 提供服务的实例,并将其共享给它的子组件(通过 providers 元数据数组),子组件可以通过构造函数将该实例注入到自身.

import { Component }          from '@angular/core';

import { MissionService }     from './mission.service';

@Component({
  selector: 'app-mission-control',
  template: `
    <h2>Mission Control</h2>
    <button (click)="announce()">Announce mission</button>
    <app-astronaut *ngFor="let astronaut of astronauts"
      [astronaut]="astronaut">
    </app-astronaut>
    <h3>History</h3>
    <ul>
      <li *ngFor="let event of history">{{event}}</li>
    </ul>
  `,
  providers: [MissionService]
})
export class MissionControlComponent {
  astronauts = ['Lovell', 'Swigert', 'Haise'];
  history: string[] = [];
  missions = ['Fly to the moon!',
              'Fly to mars!',
              'Fly to Vegas!'];
  nextMission = 0;

  constructor(private missionService: MissionService) {
    missionService.missionConfirmed$.subscribe(
      astronaut => {
        this.history.push(`${astronaut} confirmed the mission`);
      });
  }

  announce() {
    let mission = this.missions[this.nextMission++];
    this.missionService.announceMission(mission);
    this.history.push(`Mission "${mission}" announced`);
    if (this.nextMission >= this.missions.length) { this.nextMission = 0; }
  }
}

AstronautComponent 也通过自己的构造函数注入该服务。由于每个 AstronautComponent 都是 MissionControlComponent 的子组件,所以它们获取到的也是父组件的这个服务实例。

import { Component, Input, OnDestroy } from '@angular/core';

import { MissionService } from './mission.service';
import { Subscription }   from 'rxjs';

@Component({
  selector: 'app-astronaut',
  template: `
    <p>
      {{astronaut}}: <strong>{{mission}}</strong>
      <button
        (click)="confirm()"
        [disabled]="!announced || confirmed">
        Confirm
      </button>
    </p>
  `
})
export class AstronautComponent implements OnDestroy {
  @Input() astronaut: string;
  mission = '<no mission announced>';
  confirmed = false;
  announced = false;
  subscription: Subscription;

  constructor(private missionService: MissionService) {
    this.subscription = missionService.missionAnnounced$.subscribe(
      mission => {
        this.mission = mission;
        this.announced = true;
        this.confirmed = false;
    });
  }

  confirm() {
    this.confirmed = true;
    this.missionService.confirmMission(this.astronaut);
  }

  ngOnDestroy() {
    // prevent memory leak when component destroyed
    this.subscription.unsubscribe();
  }
}

相关文章

  • Angular2 父子组件通信方式

    Angular2官方文档对组件交互这块有详细的介绍-->文档--组件之间的交互。按文档介绍,组件间交互的方式一共有...

  • angular组件交互

    1.父组件通过属性绑定的方式将数组从上到下的流入到子组件中,子组件需要通过@Input装饰器来获取。 例如: 2....

  • Angular2组件间交互

    组件间交互简单来说就是让两个或多个组件之间共享信息。接下来我们就对Angular2组件间的交互做一个简单的解...

  • angular4--组件交互

    最近到了新公司,用的技术是angular4,以前只用过angular1,本来以为两者差别不大,结果了解之后才知道...

  • Angular-组件交互进阶

    Angular组件进阶 前几天, 解决了困扰许久的Angular组件自定义部分模板问题, 才准备梳理下知识, 有了...

  • Angular组件篇

    Angular组件 一:组件基础 1:什么是组件? 组件(Component)是构成Angular应用的基础和核心...

  • Angular 5 自定义文件上传组件(四)

    Angular 5 自定义文件上传组件(一)Angular 5 自定义文件上传组件(二)Angular 5 自定义...

  • 2019-11-03

    angular8 angular ngFor 遍历map 数据 使用keyvalue 管道 angular 在组件...

  • angular2 组件之间传值及事件传递

    简介 angular2及以后的版本(包括angular4)都称为angular。组件之间的传值主要分为父子组件间传...

  • 样式封装&组件间通信

    关于样式 angular 可以将样式封装在组件本身中,不会影响其他组件的样式(默认)Angular 会修改组件的 ...

网友评论

      本文标题:angular组件交互

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