Angular中使用@Input、@Output 和 @ViewChild 的基本示例


提示:以下是本篇文章正文内容,下面案例可供参考

一、@Input

在父组件中,我们有一个message属性,我们想将其传递给子组件以显示。

ParentComponent (parent.component.ts)代码如下(示例):

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

@Component({
  selector: 'app-parent',
  template: `
    <app-child [childMessage]="parentMessage"></app-child>
  `,
})
export class ParentComponent {
  parentMessage = 'message from parent';
}

ChildComponent (child.component.ts)代码如下(示例):

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

@Component({
  selector: 'app-child',
  template: `
    {{ childMessage }}
  `,
})
export class ChildComponent {
  @Input() childMessage: string;
}

二、@Output

在子组件中,我们有一个按钮,当点击这个按钮时,我们想将一个事件发送到父组件。

ChildComponent (child.component.ts)如下(示例):

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

@Component({
  selector: 'app-child',
  template: `
    <button (click)="sendMessage()">Send Message</button>
  `,
})
export class ChildComponent {
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit('Hello from Child Component!');
  }
}

ParentComponent (parent.component.ts)如下(示例):

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

@Component({
  selector: 'app-parent',
  template: `
    <app-child (messageEvent)="receiveMessage($event)"></app-child>
  `,
})
export class ParentComponent {
  childMessage: string;

  receiveMessage($event: string) {
    this.childMessage = $event;
  }
}

三、@ViewChild

ChildComponent (child.component.ts)代码如下(示例):

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

@Component({
  selector: 'app-child',
  template: `
    Welcome to the app!
  `,
})
export class ChildComponent {
  greet() {
    alert('Hello from Child Component!');
  }
}

ParentComponent (parent.component.ts)代码如下(示例):

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <app-child></app-child>
    <button (click)="callChildMethod()">Call Child Method</button>
  `,
})
export class ParentComponent implements AfterViewInit {
  @ViewChild(ChildComponent) childComponent: ChildComponent;

  ngAfterViewInit() {
    // ViewChild is set after the view has been initialized
    this.childComponent.greet();
  }

  callChildMethod() {
    this.childComponent.greet();
  }
}

四、@Input、@Output、@ViewChild和RXJS结合使用案例

@Input,@Output 与 RxJS 非常好地结合在一起,特别是在处理异步操作和复杂事件流时。

4.1 @Input 和 RxJS

如果你的 @Input 属性频繁改变,你可能会想要对这些改变进行响应,例如,执行一个复杂的计算,或者从服务器加载相关的数据。在这种情况下,你可以使用 RxJS 的 Subject 和 switchMap 操作符:

private _data = new Subject<Data>();

@Input()
set data(value: Data) {
  this._data.next(value);
}

ngOnInit() {
  this._data.pipe(
    switchMap(data => this.loadData(data))
  ).subscribe(result => {
    // 处理结果
  });
}

每次 @Input 属性改变时,都会调用 loadData 函数,并自动取消之前的调用,如果它还在执行的话。

4.2 @Output 和 RxJS

@Output 属性通常是 EventEmitter 的实例,但 EventEmitter 本身就是 RxJS Subject 的子类,所以你可以用所有 RxJS 操作符处理 @Output 事件:

@Output() event = new EventEmitter<Event>();

ngOnInit() {
  this.event.pipe(
    debounceTime(500)
  ).subscribe(e => {
    // 处理事件,但如果在500毫秒内有新事件,这个事件将被忽略
  });
}

这样,你可以使用 debounceTime 操作符来防止事件的频繁触发。

4.3 @ViewChild 和 RxJS

可以在一个 @ViewChild 查询的结果上使用 RxJS 操作符。例如,你可能有一个视图子组件,这个子组件有一个返回 Observable 的方法,你可以在这个 Observable 上使用 switchMap,mergeMap,concatMap 等操作符:

@ViewChild(ChildComponent) child: ChildComponent;

ngOnInit() {
  this.child.getData().pipe(
    switchMap(data => this.processData(data))
  ).subscribe(result => {
    // 处理结果
  });
}

这样,每次子组件的数据改变时,都会调用 processData 函数,并自动取消之前的调用,如果它还在执行的话。

五、总结

相同点:

都是装饰器,用来标注类的成员变量。都用于实现组件之间的交互。

不同点:

@Input:它允许外部组件或者说父组件向子组件传递数据。它相当于子组件的公开属性,可以接收父组件的输入。@Input 装饰的变量表示输入属性,我们可以在模板表达式中绑定到这个输入属性上。

@Output:它允许子组件向父组件发送事件和数据。@Output 装饰的变量通常是 EventEmitter 的实例,用来发射事件。当子组件需要通知父组件某个事件时,可以调用这个 EventEmitter 的 emit 方法,然后父组件可以绑定到这个事件上。

@ViewChild:它允许一个组件内部访问其子组件的实例。使用此装饰器,父组件可以直接调用子组件的方法或访问其数据成员。@ViewChild 接收一个类类型或者模板引用变量名,然后会返回对应的类实例或者模板引用变量的值。

@Input 和 @Output 主要用于父子组件之间的数据交互,而 @ViewChild 则更多的是用于在一个组件内部访问其子组件。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@WangXingYu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值