将信息从 Angular 组件发送到另一个同级组件的智能解决方案是什么?

What is a smart solution to send information from an Angular component to another sibling component?

我是 Angular 的新手,我对允许将两个组件传送到我的应用程序中的好方法有疑问。我知道存在不同的策略,我想了解什么对我的具体情况是一个好的选择。

基本上我的情况是这样的:

正如您在前面的屏幕截图中看到的,我有两个组件:

所以基本上当我单击组件 1(人员列表)中的漏斗图标时,将执行此组件打字稿代码中的以下方法:

onClickFilter(人,事件){ console.log("onClickFilter 开始。人是:", 人); }

person 对象是包含我必须发送到组件 2(右边的日历组件)的信息的对象。

我在这里阅读有关如何允许组件通信的内容:

https://medium.com/@mirokoczka/3-ways-to-communicate-between-angular-components-a1e3f3304ecb

还有这里:https://angular.io/guide/component-interaction

但我不知道什么是最好的选择。特别是在官方 Angular 文档中,我可以找到从父级传递给子级的方法(但这里这些组件是兄弟姐妹)。

一个想法是在组件 1(人员列表)中发出一个事件并在组件 2(日历)中订阅它,但我不确定它是否太紧了。

在此用例中什么是智能解决方案?

第一个

使用Input()装饰器传递数据。在您的情况下,将数据发送到另一个组件的是 parent。接收数据的人是 Child。当您需要将数据从 Parent 发送到 Child 时,我们使用 @Input()。当我们需要将数据从 Child 发送到 Parent 时,我们使用 @OutOut()EventEmitter.

在你的情况下,它的定义组件 1 是 Parent,组件 2 是 child。

在您的 component1.ts 文件中,定义应该将数据传递给组件 2 的 属性。在我的例子中,假设是 personDetails。并在您的 onclick 方法中执行您的操作并将详细信息分配给 personDetails 属性.

export class Component1  {
  personDetails: ShiftDetail;

  onClickFilter(data: any) {
    // do the logics
    this.personDetails = data;
  }
}

在您的 component2.ts 文件中定义一个带有 @Input() 装饰器的 属性。 属性 将从 component1 获取详细信息。

export class Component2  {
  @Input() personDetailsInput: ShiftDetail;
}

要将组件 1 的 属性 personDetails 中的详细信息分配给组件 2 的 personDetailsInput,请使用 component1.html 文件。使用 属性 绑定来分配值。

<component2 [personDetailsInput]="personDetails"></component2>

作为参考,请使用 Angular 官方文档。英雄反派APP将定义一切

我不清楚您的应用程序是如何设置的。我看到了人员列表视图和日历视图,您称他们为“兄弟姐妹”,但我并不完全清楚导航是如何工作的。这是我看到的选项。

  1. 如果列表视图和日历同时出现在屏幕上,它们实际上是同级组件,并且都是父组件的子组件。所以对子 A 的点击可以通过 Emit 向上传递给父,然后通过 ViewChild 向下传递回子 B。

  2. 在列表视图中单击用户可能会将您“路由”到日历视图,在这种情况下,使用 queryParams 可以很好地将 userId 传递给日历

  3. 单击用户可能会弹出日历的弹出模式,这意味着您可以使用 ViewChild 将数据直接从视图 A 传递到视图 B。或者甚至跳过 ViewChild 并直接使用 html 标签传递数据。

如果您想在两个不属于父子关系的组件之间传递数据 - 最好的解决方案是使用服务和 Subject 的概念。

我们如何使用它?

首先,创建data.service.ts

@Injectable({
  providedIn: 'root'
})
export class DataService {

  constructor() { }

  dataToBePassed = new Subject<any>();
  dataToBePassedObs = this.dataToBePassed.asObservable();
  
  changeData(newData: any) {
    this.dataToBePassed.next(newData);
  }

}

然后您需要在要共享数据的两个组件中注入此服务。一侧将继续发送数据,另一侧将监听(通过订阅)。

listener-sibling.component.ts

export class ListenerSibling implements OnInit {

  someData: any;

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
    this.dataService.dataToBePassedObs().subscribe((data) => {
        this.someData = data;
    })
  }

}

sender-sibling.component.ts

export class SenderComponent implements OnInit {

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
  }

  sendData() {
    this.dataService.changeData('sending new data');
  }

}