绑定 Angular 中两个 child 组件的输入和输出的最佳方式

Best way to bind inputs and outputs of two child components in Angular

这是一个更笼统的问题,所以我也提供了笼统的信息。在 Angular 中,我使用了一个 parent 组件,其中包含 2 个 child 组件。这 2 child 个组件需要相互共享信息:

<parent-component>
   <child1-component></child1-component>
   <child2-component></child2-component>
</app-parent>

因此,child1 需要来自 child2 的信息,而 child2 需要来自 child1 的信息(及其不同的信息)。 child1 和 child2 不在一个组件中的原因(因为这当然可以解决问题)是它是一个非常大的组件,我想使用 child 1 在另一页没有 child2.

所以我已经找到了 2 个解决方案:

1:处理parent中child的所有输出,并为它们提供输入。这意味着对于 child 具有的每个输出(child1 或 child2),parent 必须为其实现一个处理程序,指定一个变量并绑定它到另一个 child.

的输入

2:使用在两个 child 中都注入的服务。一个 child 调用服务的一个方法,它触发和事件将由另一个 child 直接处理。

现在您认为最好的方法是什么?还是有第三种甚至更好的方法?

提前致谢,赫尔曼

如果变量包含的数据类型与 UI 相关,请不要用服务挤占代码] 并按照您认为合适的方式将它们传递出去,但是如果您正在向服务器发出一些请求或加载数据,那么最好为它们发出请求,但是您应该再次将其注入 parent 因为因为两个 child 组件需要它 这比在 childs

中注入你的服务要好得多

您在这里真正得到的是共享状态管理。有许多工具可以帮助您解决这个问题。查看 Akita for example. NGRX 也很受欢迎。但要回答您的问题,您可以直接使用 RxJS 创建一个简单的状态管理服务。让我们从示例服务开始:

import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable } from "rxjs";
import { State } from "./components/state.model";

/**
 * Manages simple state for app.
 */
@Injectable({ providedIn: "root" })
export class StateService {
  /**
   * State behavior contains state of the app.
   */
  private stateSub = new BehaviorSubject<State>({
    message: "Initial state",
    modifiedBy: "System"
  });

  /**
   * An observable with our shared state.
   */
  public state: Observable<State> = this.stateSub.asObservable();

  /**
   * Set app state.
   */
  public setState(message: string, modifiedBy: string) {
    this.stateSub.next({
      message: message,
      modifiedBy: modifiedBy
    });
  }
}

接下来,这是一个消耗此状态的组件:

<h1>Component 1</h1>
<!-- Capturing observable in template var to prevent multiple subscriptions. -->
<ng-container *ngIf="(appState$ | async) as appState">
  <p><strong>Message: </strong>{{ appState.message }}</p>
  <p><strong>Set by: </strong>{{ appState.modifiedBy }}</p>
</ng-container>
<button (click)="setMessage()">Modify app state</button>

...组件逻辑:

export class Component1 implements OnDestroy {
  appState$: Observable<State>;
  unsubscribe$ = new Subject();

  constructor(private state: StateService) {
    // Unsubscribe to avoid memory leaks.
    this.appState$ = this.state.state.pipe(takeUntil(this.unsubscribe$));
  }

  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  setMessage() {
    this.state.setState("Component 1 rules!", "Component 1");
  }
}

创建更多具有相同逻辑的组件,它们都可以订阅您的状态更改并通过状态服务自行修改状态。它很简单,它是惯用的,并且添加了零依赖性。我在 medium/large Angular 项目中使用了类似的方法,并且通常更喜欢滚动我自己的状态管理器服务而不是其他方法。此外 - 你对大量 input/output 参数的第一个想法在较大的项目中很快变得难以管理,所以我会避免它。一般来说,您应该尝试将尽可能多的繁重工作卸载到服务,以希望保持组件清洁。

最后,here's a working example on stackblitz。试一试,修改成你想要的状态等