gpt4 book ai didi

angular - 如何在 Angular 6 中实现延迟组件投影?

转载 作者:行者123 更新时间:2023-12-05 06:31:44 25 4
gpt4 key购买 nike

Here is the code example我会引用。这是一个 stackblitz 项目,精简为解释问题所需的裸组件。

所以我想做的是能够将一个组件作为另一个组件的子组件传递,但是这个父组件应该能够阻止它的创建,直到它决定要创建它。在示例中,我传递的 app.component.html 文件 <app-action>小时候<app-projector>我想要 <app-projector>能够推迟实际创建 <app-action>一段时间。

<app-projector>组件实际上不能引用 ActionComponent通过 ContentChildren 的 ts 类,因为它应该可以是任何组件。

我当前的 stackblitz 示例尝试使用 <ng-template>在投影仪组件中,但如您所见,它确实在投影仪组件决定实际呈现模板中的内容之前创建组件并运行组件生命周期函数。我想这样做,以便在我们准备好呈现作为内容传递的组件之前,我们不会启动生命周期函数或创建组件。

有什么想法吗?

最佳答案

问题的根源是 <ng-content>发生在构建时——你转换到其中的任何组件都将在构建时而不是运行时创建! ( source ) 这就是为什么在您的 StackBlitz 中, <app-action>组件在屏幕上显示之前已经开始计数。而不是使用 <ng-content>对于延迟内容投影,您应该使用以下方法。

(查看 StackBlitz demo 以查看它是否按预期工作)


创建结构指令

结构指令是改变 DOM 结构的指令,例如通过添加、删除或操作元素。例如,ngIfngFor是结构指令。关于结构指令的事情是 Angular 自动将指令的宿主元素“转换”为 <ng-template>。如果你放一个星号 *指令前面的前缀。例如,这个:

<div *ngIf="myCondition">Lorem ipsum</div>

...由 Angular 自动转换为:

<ng-template [ngIf]="myCondition">
<div>Lorem ipsum</div>
</ng-template>

因此,如果我们创建自己的结构指令,称为 delayedContent并将其应用于 <app-action> 之类的组件/元素:

<app-action *delayedContent></app-action>

...然后它会被转换成这样:

<ng-template delayedContent>
<app-action></app-action>
</ng-template>

这是 delayedContent 的 TS 文件:

@Directive({
selector: '[delayedContent]'
})
export class DelayedContentDirective {
constructor(templateRef: TemplateRef<void>, projector: ProjectorComponent) {
projector.allDelayedContent.push(templateRef);
}
}

在这里我可以使用TemplateRef获得对 <ng-template> 的引用Angular 生成的元素,然后推送 TemplateRef到父级数组 <app-projector>组件。

<app-projector>组件,我们现在可以取 TemplateRefs并将它们显示在您的 <ng-container> 中.现在你的 <app-action>组件只会在 createEmbeddedView() 时创建被调用,所以它会在显示时从 0 开始计数(而不是从 3 开始)。

@Component({
selector: 'app-projector',
templateUrl: './projector.component.html'
})
export class ProjectorComponent implements AfterViewInit {
// All the TemplateRefs to the delayed content will be stored in this array
allDelayedContent: TemplateRef<void>[] = [];

@ViewChild('container', { read: ViewContainerRef }) _container: ViewContainerRef;

constructor() { }

ngAfterViewInit() {
// Show this after 3 seconds
setTimeout(() => {
this._container.createEmbeddedView(this.allDelayedContent[0]);
}, 3000)

// You can add other elements to the `allDelayedContent` array and show them here
// Show this after 5 seconds
setTimeout(() => {
this._container.createEmbeddedView(this.allDelayedContent[1]);
}, 5000)

// Show this after 7 seconds
setTimeout(() => {
this._container.createEmbeddedView(this.allDelayedContent[2]);
}, 7000)
}
}

看看这个 second StackBlitz demo .它具有 delayedContent 的修改版本允许您直接在 HTML 中指定延迟时间的结构指令,如下所示:

<app-projector>
<app-action *delayedContent="3000"></app-action>
<div *delayedContent="2000">Some delayed content</div>
<div *delayedContent="6000">More delayed content</div>
<app-projector>

关于angular - 如何在 Angular 6 中实现延迟组件投影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51675333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com