利用Angular的依赖注入,让你的父母获得自由

126 阅读3分钟

利用Angular的依赖注入功能让你的父母获得自由

[

Yoko Ishioka

](medium.com/@yoko_65687…)

石冈洋子

关注

11月4日 - 3分钟阅读

planes flying to goal

来源。Freepik

如果你正在使用一个模块化、组件驱动的架构,你将面临的最大挑战之一是如何实现父子组件/指令之间的沟通。一方面,你希望每个组件/指令都能独立地专注于它们的目的。另一方面,你需要它们一起工作,就像它们是作为一个有凝聚力的单元建立的。

幸运的是,Angular为任何类型的情况都提供了你所需要的东西

如果你的父视图包含了子视图,一个常见的方法是使用@Input()和@Output()装饰器。为了与父视图通信,你可以通过子视图发出自定义事件。为了与子代沟通,你可以传递与父代绑定的属性。

你也可以使用@ViewChild/@ViewChildren@ContentChild/@ContentChildren来打破父/子间的隔阂。(我将在以后的文章中讨论这些强大的装饰器)。)

如果你的父视图不直接包含子视图,或者根本不存在任何关系,你可以在服务中使用观测器来交流数据。这样一来,实际的关系并不重要,因为任何注入服务的人都可以更新和订阅观察者。

为什么使用依赖注入来寻找父类

我创建了一个任务系统,在一个表行组件中显示每个任务。我还创建了按钮组件来对表行进行操作。然而,我不想把按钮组件包含在表行组件中,这样它们就可以被使用,不管它们是否在表中。

我面临的问题是如何给按钮组件分配一个特定的ID,而不需要一次又一次地把ID作为一个输入来传递。例如,这里是表行组件的HTML,它在一个任务数组上进行迭代。

<ces-table-row *ngFor="let task of tasks; let index = index;" [id]="task.id" [index]="index">    <ces-table-column class="justify-center">        <ces-view-pin [active]="task.pinned"></ces-view-pin>        <ces-view-delete></ces-view-delete>    </ces-table-column>    <ces-table-column class="justify-center">{{ task.id }}</ces-table-column>    <ces-table-column class="justify-center">        <ces-task-menu-statuses [default]="task.status"></ces-task-menu-statuses>    </ces-table-column>    <ces-table-column>{{ task.dateUpdated | date: 'short' }}</ces-table-column>    <ces-table-column>{{ task.title }}</ces-table-column>    <ces-table-column>{{ task.notes }}</ces-table-column></ces-table-row>

我提到的按钮组件使用选择器 "ces-view-pin "和 "ces-view-delete"。我希望这些组件只负责按钮的交互状态,并在它们被按下时向一个服务发送一个消息。这样,我就可以避免每次使用它们时重复多余的代码,而且无论谁在使用它们,它们的行为都是一样的。

由于表行组件正在获取任务ID,我需要一种方法来浏览层次结构来访问它。值得庆幸的是,Angular提供了一种简单的方法来搜索层次结构

搜索一个父接口

第一步:创建一个抽象类

我首先创建了一个抽象类,其中包含我希望按钮组件能够访问的属性。

export abstract class View {  abstract id: number;  abstract index: number;}

第2步:实现抽象类并添加提供者

下一步是实现这个抽象类,并为试图注入它的人提供一个引用。

import { Component, forwardRef, Input } from '@angular/core';import { View } from 'projects/view/src/public-api';

第3步:将接口注入子组件/指令中

最后一步是使用@Optional()装饰器将视图类注入任何需要访问抽象类中定义的父类属性/方法的子类。

export class ViewDeleteComponent {

如果你想看所有三个组件的代码,请查看这个github gist