angular组件交互

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

例如:

父组件为
@Component({
      template: `
          
` }) export class ListComponent implement OnInit{ this.contacts = data; }
子组件为:
@Component({
        template:`
             
` }) export class ListItemComponent implements OnInit{ @Input() contact: any = {}; }
2.子组件通过事件传递的方式向父组件传递数据,子组件需要实例化EventEmitter类,并使用装饰器@Output修饰这个输出属性。父组件通过事件绑定的方式来订阅来自子组件触发的事件。
父组件:
@Component({
        template: `
            
        `
})
export class CollectionComponent implements OnInit{
        detail: any = {};
        collectTheContact(){
              this.detail.collection == 0 ? this.detail.collection = 1 : this.detail.collection = 0;  
      }
}
父组件通过绑定自定义事件onCollect订阅来自子组件触发的事件。
子组件
@Component({
      template: `收藏`
})
export class ContactCollectComponent{
      @Input() contact: any = {};
      @Output() onCollect = new EventEmitter();
      collectTheContact(){
          this.onCollect.emit();
      }
}

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

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

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

父组件:
@Component({
      template:`
            
      `
})
export class CollectionComponent{}
在父组件中为子组件创建了一个局部变量#collect,父组件就可以使用#collect调用子组件的方法collectTheContact()
子组件
@Component({
        template:收藏
})
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;

参数为类实例
@Component({
      template:`
            
`
})
export class CollectionComponent{
      @ViewChild(ContactCollectComponent) contactCollect: ContactCollectComponent;
      ngAfterViewInit(){}
      collectTheContact(){
            this.contactCollect.collectTheContact();
      }
}
组件内容嵌入

标签用来渲染组件嵌入内容。
例如:

@Component({
    selector: 'example-content'
    template: `
        

ng-content实例

` }) class NgContentExampleComponent{} 中有一个select="header",用于匹配内容。并填充到ng-content中。
使用
@Component({
      selector:'app'
      template:`
          
                
Header content
` }) export class NgContentAppComponent{}
最后渲染成的是

    
        

ng-content

Header content
从图中可以看出
Header content
被填充到了ng-content,select属性是一个选择器,类似于css的选择器,可以有标签选择器、类选择器、属性选择器。

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

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

@Component({
  selector: 'app-name-child',
  template: '

"{{name}}"

' }) export class NameChildComponent { private _name = ''; @Input() set name(name: string) { this._name = (name && name.trim()) || ''; } 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: `
    

Version {{major}}.{{minor}}

Change log:

  • {{change}}
` }) 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: `

Source code version

` }) 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();
  private missionConfirmedSource = new Subject();

  // 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: `
    

Mission Control

History

  • {{event}}
`, 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: `
    

{{astronaut}}: {{mission}}

` }) export class AstronautComponent implements OnDestroy { @Input() astronaut: string; mission = ''; 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(); } }

你可能感兴趣的:(angular组件交互)