typescript Angular 6 -多个子组件应该属于同一个示例

zfycwa2u  于 2023-05-19  发布在  TypeScript
关注(0)|答案(4)|浏览(98)

我简化了我的问题:

<div *ngIf="layout1" class="layout1">
  <div class="sidebar-layout1">
     some items
  </div>
  <child-component [something]="sth"></child-component>
</div>
<div *ngIf="!layout1" class="layout2">
  <child-component [something]="sth">
    <p>some content...</p>
  </child-component>
</div>

我有一个父组件,它有一个正常的布局(layout1)和一个全屏布局(layout2)的可能性(在全屏模式下,子组件应该在全屏)。问题是,当我用 *ngIf更改布局时,子组件被破坏,并生成一个新组件。我想有相同的示例,不松散的子组件的重要信息,并避免一些API调用。
有没有什么方法可以使子组件不被破坏,或者有没有比ngIf更好的方法?
我只需要一个子组件的父组件中的不同布局的示例。

3pmvbmvn

3pmvbmvn1#

正如你可能已经注意到的,如果你使用*ngIf隐藏元素,那么就会创建一个新的组件。这是我们将努力关注的,并尽量避免创建新组件。
为此,我们可以使用“切换器布局”并将子组件作为内容传递

<app-layout-switcher [layout1]="layout1">
  <ng-container>
    <child-component
      *ngIf="sth$ | async as sth; else loading"
      [something]="sth"
    >
      <p>some content...</p>
    </child-component>
    <ng-template #loading>
      <h1>Loading...</h1>
    </ng-template>
  </ng-container>
</app-layout-switcher>

我添加了一个模拟http调用来显示加载。
在我们的app-layout-switcher组件中,我们可以根据需要在布局之间切换。我们将child-component传递到模板中,以便能够在布局中重用它

<div *ngIf="layout1">
  <app-layout-1>
    <ng-template [ngTemplateOutlet]="childComponent"></ng-template>
  </app-layout-1>
</div>

<div *ngIf="!layout1">
  <app-layout-2>
    <ng-template [ngTemplateOutlet]="childComponent"></ng-template>
  </app-layout-2>
</div>

<ng-template #childComponent>
  <ng-content></ng-content>
</ng-template>

现在我们可以在布局中使用模板了

<header>
  <h1>Layout 1</h1>
</header>
<main>
  Contents in Layout 1
  <div>
    <ng-content></ng-content>
  </div>
</main>

<footer>Layout 1 Footer</footer>

我们现在只使用组件的一个示例。为了确认这一点,我在演示中添加了一个文本字段。您会注意到,在切换布局时,数据是持久化的

See this Demo

xurqigkl

xurqigkl2#

使用[hidden]属性代替反向逻辑,它将防止元素销毁。

<div [hidden]="!layout1" class="layout1">
...
</div>
<div [hidden]="layout1" class="layout2">
...
</div>

我隐藏只是隐藏/显示DOM元素与CSS通过改变显示风格

4zcjmb1e

4zcjmb1e3#

您可以通过几个步骤实现这一点:
1.使用以下命令创建服务:

ng generate service data-passing

1.在服务中定义两个变量,用于保存每个组件的数据:

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

@Injectable({
  providedIn: 'root',
})
export class DataPassingService {
  public firstComponentData;
  public secondComponentData;

  constructor() { }

}

1.在组件中使用服务:

import {DataPassingService} from '...';

...
constructor(public dataPassingService: DataPassingService) {
}

1.将每个组件数据存储在相对变量中:

setDate(first, second) {
  this.dataPassingService.firstComponentData = first;
  this.dataPassingService.secondComponentData = second;
}

1.使用之前使用的*ngIf控制零部件可见性:

<div *ngIf="layout1" class="layout1">
  <div class="sidebar-layout1">
     some items
  </div>
  <child-component [something]="dataPassingService.firstComponentData"></child-component>
</div>
<div *ngIf="!layout1" class="layout2">
  <child-component [something]="dataPassingService.secondComponentData">
    <p>some content...</p>
  </child-component>
</div>
fafcakar

fafcakar4#

当你想在两个不同的布局中显示相同/不同的细节时:

  • 实现用于状态管理的秋田存储https://datorama.github.io/akita/docs/store
  • 从父组件本身的服务中获取所需的所有数据。
  • 将从服务接收的数据更新到存储中。
  • 通过在两种布局中使用查询订阅商店。
  • 更新用户在商店中进行的最新更新。

相关问题