• 技术文章 >web前端 >js教程

    Angular组件怎么进行通信?父子组件通信的2种方法

    青灯夜游青灯夜游2021-08-20 10:02:42转载230
    本篇文章带大家了解一下Angular中的组件通信,介绍一下父子组件间通信、无直接关系组件间通信的方法。

    在实际的应用中我们的组件将会以树形的结构进行关联,所以组件间的关系主要就是:

    • 父子关系

    • 兄弟关系

    • 无直接关系

    【相关教程推荐:《angular教程》】

    准备一下我们的环境:

    1、创建一个header组件: ng g c components/header

    <app-button></app-button>
    <app-title></app-title>
    <app-button></app-button>
    export class HeaderComponent implements OnInit {
    
      constructor() {}
    
      ngOnInit(): void {}
    }

    2、创建一个title组件: ng g c components/title

    <span>{{title}}</span>
    export class TitleComponent implements OnInit {
    
      public title: string = '标题';
    
      constructor() {}
    
      ngOnInit(): void {}
    }

    3、创建一个button组件: ng g c components/button

    <button>{{ btnName }}</button>
    export class ButtonComponent implements OnInit {
      public btnName: string = '按钮';
    
      constructor() {}
    
      ngOnInit(): void {}
    }

    直接调用

    适用于父子关系组件,注意点是直接调用使得父子组件的耦合性变高,要明确使用确实需要直接调用。

    1、将我们的header组件挂载到app中,使得app和header之间形成父子组件关系

    2、使用#为我们的组件起一个名称: <app-header #header></app-header>

    3、现在我们的header组件还很空,我们扩展一下,要不然调用什么呢?

    export class HeaderComponent implements OnInit {
      public name: string = 'HeaderComponent';
    
      printName(): void {
        console.log('component name is', this.name);
      }
    }

    4、组件扩展好以后我们就可以在父组件app中调用子组件header中的属性和函数了

    <app-header #header></app-header>
    <p>
      调用子组件属性: {{ header.name }}
      <button (click)="header.printName()">调用子组件函数</button>
    </p>

    5、第4步是在父组件的html模板中进行操作,有时候我们还需要在父组件的ts类中对子组件进行操作,我们接下来接着演示。

    6、我们需要用到一个新的装饰器@ViewChild(Component)

    export class AppComponent {
      title = 'angular-course';
    
      @ViewChild(HeaderComponent)
      private header!: HeaderComponent;
    
    	// 声明周期钩子: 组件及子组件视图更新后调用,执行一次
      ngAfterViewInit(): void {
        // 调用子组件属性
        console.log(this.header.name);
        // 调用子组件函数
        this.header.printName();
      }
    }

    @Input和@Output

    适用于父子关系组件

    1、我们通过在header组件中定义title,来解耦title组件中直接调用导致扩展复杂的问题

    2、为title组件中的title属性增加@Input()装饰器: @Input() public title: string = '标题';

    3、为header组件新增title属性并赋值: public title: string = '我是新标题';

    4、我们再header组件的html模板中这样来使用title组件: <app-title [title]="title"></app-title>

    5、一起看看到现在的效果吧,界面虽然丑,但是下次使用组件时title设置是不是方便一点呢?

    image.png

    6、以上步骤实现了父组件的数据传递到了子组件中,那么我们接着来看子组件的数据怎么传递到父组件中呢? 我们一起来用@Output()装饰器实现以下吧

    7、在title组件的ts类中增加titleChange属性: @Output() public titleChange = new EventEmitter();

    8、在title组件的ts类中定时派发数据

    ngOnInit(): void {
      // 定时将子组件的数据进行派发
      setInterval(() => {
      	this.titleChange.emit(this.title);
    	}, 1500);
    }

    9、现在我们来修改header父组件来接收派发来的数据:

    <app-title 
    	[title]="title" 
      (titleChange)="onChildTitleChange($event)">
    </app-title>
    onChildTitleChange(value: any) {
    	console.log('onChildTitleChange: >>', value);
    }

    利用服务单利进行通信

    适用于无直接关系组件

    image.png

    1、既然要通过服务来做通信,那我们就先创建一个服务吧: ng g s services/EventBus,并且我们声明了一个类型为Subject的属性来辅助通信

    @Injectable({
      providedIn: 'root',
    })
    export class EventBusService {
      public eventBus: Subject<any> = new Subject();
    
      constructor() {}
    }

    2、我们为了省事就不重新创建组件了,因为我们的header中的按钮组件和title组件就符合没有直接关系的组件。

    3、改造一下我们的button组件,并且添加点击事件来触发triggerEventBus函数

    export class ButtonComponent implements OnInit {
      public btnName: string = '按钮';
    
      constructor(public eventBusService: EventBusService) {}
    
      ngOnInit(): void {}
    
      public triggerEventBus(): void {
        this.eventBusService.eventBus.next('我是按钮组件');
      }
    }

    4、在title组件中模拟数据的获取

    export class TitleComponent implements OnInit {
    
      constructor(public eventBusService: EventBusService) {}
    
      ngOnInit(): void {
        this.eventBusService.eventBus.subscribe((value) => {
          console.log(value);
        });
      }
    }

    利用cookie、session或者localstorage进行通信

    image.png

    1、这个就很简单了,我们还是用title组件和button组件来做演示,这次我们在title组件中将数据保存,在button组件中获取数据。我们仅演示localstorage吧,其他都雷同的。

    2、在title组件的ngOnInit()钩子中保存titlelocalstorage中: window.localStorage.setItem('title', this.title);

    3、在button组件中获取数据: const title = window.localStorage.getItem('title');

    结语:

    本篇我们介绍了Angular的组件通信,为我们拆分后的组件可以进行合理的通信提供了保障,我们到现在组件的使用都是通过引入标签的方式进行。

    原文地址:https://juejin.cn/post/6991471300837572638

    作者:小鑫同学

    更多编程相关知识,请访问:编程入门!!

    以上就是Angular组件怎么进行通信?父子组件通信的2种方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:Angular 组件通信
    上一篇:Node.js如何使用文件系统模块?常用fs模块方法介绍 下一篇:用JavaScript绘制一个渐变圆圈对角线
    大前端线上培训班

    相关文章推荐

    • 对angular的组件通信的解析• 5种Angular中组件通信的方法介绍• 聊聊Angular中的单元测试• 了解angular10模块相关概念,快速入门!

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网