如何重用包装更新其内容的 Viewchild 的 ngTemplate

How to reuse an ngTemplate which wraps a Viewchild that updates it's content

我想重用一个带有动态变化的 viewchild 的 ng-template,并让它在我重用 ng-template 的所有地方更新。但是它并没有在所有地方更新。

当我像这样将 ng-template 的内容设为静态时,它会起作用:

<h2>Position 1</h2>
<ng-container [ngTemplateOutlet]="statusTemplate"></ng-container>
<h2>Position 2</h2>
<ng-container [ngTemplateOutlet]="statusTemplate"></ng-container>
<ng-template #statusTemplate>
  <h3>Saved</h3>
</ng-template>

输出以下内容HTML:

然而,当我在 ng-template 中创建 h3 视图子视图并尝试动态更新它时,它不会在两个地方更新。

例如

<h2>Position 1</h2>
<ng-container [ngTemplateOutlet]="statusTemplate"></ng-container>
<h2>Position 2</h2>
<ng-container [ngTemplateOutlet]="statusTemplate"></ng-container>
<ng-template #statusTemplate>
  <h3 #status></h3>
</ng-template>

然后我让这段代码动态设置视图子项的内部内容,但是更新没有出现在两个地方我重新使用模板

@ViewChild('status', { static: false })
public status: any;

public setStatusTo(name: string): void {
  this.status.nativeElement.innerHTML = name;
}

html在浏览器中运行时是这样的

  <h2 _ngcontent-rdv-c3="">Position 1</h2>
  <!--bindings={
    "ng-reflect-ng-template-outlet": "[object Object]"
  }-->
  <h3 _ngcontent-rdv-c3="">Success</h3>
  <h2 _ngcontent-rdv-c3="">Position 2</h2>
  <!--bindings={
    "ng-reflect-ng-template-outlet": "[object Object]"
  }-->
  <h3 _ngcontent-rdv-c3=""></h3><!---->

如何实现在多个地方更新重用的 ng-template?为什么这不起作用?

因此,您可以像替代方案一样添加到您的组件中:

public status$: ReplaySubject<string> = new ReplaySubject();

然后改用它h3

{{status$ | async}}

如果您需要根据状态传递 html,您可以创建组件来根据状态进行传递。

<status-viewer [status]="status$ | async"><status-viewer>

我不会这样做(将 h3 的内容保存在一个变量中然后简单地绑定它似乎更容易)但是如果你想采用这种方法,我会使用 ViewChildren 而不是ViewChild

import { Component, ViewChild, ViewChildren } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  @ViewChildren('status')
  public statusElements: any;

  public setStatusTo(name: string): void {
    this.statusElements.toArray().forEach(
      (status) => {
        status.nativeElement.innerHTML = name;
      }
    ) 
  }
}

你可以在这里看到整个工作:https://stackblitz.com/edit/angular-af19ma