简体   繁体   English

Angular 9 ng-模板

[英]Angular 9 ng-template

I have a angular template which contains a ng-template.我有一个包含 ng 模板的 angular 模板。 I have tried to insert an embedded view via ngTemplateOutlet.我试图通过 ngTemplateOutlet 插入嵌入式视图。 However I always get the following error:但是我总是收到以下错误:

core.js:4061 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. core.js:4061 ERROR 错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。 Previous value: 'undefined'.以前的值:'未定义'。 Current value: '[object Object]'.当前值:“[对象对象]”。

This is the part where I am trying to use ngTemplateOutlet这是我尝试使用 ngTemplateOutlet 的部分

<ng-template [ngTemplateOutlet]="headerLogoMiniComponent?.templateRef"></ng-template>

If i remove this line, the error will fix.如果我删除此行,错误将修复。 What should I do to solve this problem without remove the mentioned part?在不删除提到的部分的情况下,我应该怎么做才能解决这个问题?
I suppose that I should add a condition with *ngIf for that wait headerLogoMiniComponent to be loaded.我想我应该使用*ngIf添加一个条件,以便加载等待headerLogoMiniComponent (But I don't know how to do that) (但我不知道该怎么做)

The declaration looks like the following:声明如下所示:

@Component({
  selector: 'mk-layout-header-logo-mini',
  template: '<ng-template #templateRef><ng-content></ng-content></ng-template>'
})

export class HeaderLogoMiniComponent {   

@ViewChild('templateRef',{static: false}) public templateRef:TemplateRef<any>; }

@ContentChild(HeaderLogoMiniComponent, {static: false}) public headerLogoMiniComponent: HeaderLogoMiniComponent;

Probably you have to check the Angular lifecycle hooks.可能您必须检查 Angular 生命周期挂钩。

  1. ngOnChanges() ngOnChanges()

Called before ngOnInit() and whenever one or more data-bound input properties change.在 ngOnInit() 之前以及一个或多个数据绑定输入属性更改时调用。

Respond when Angular sets or resets data-bound input properties.当 Angular 设置或重置数据绑定输入属性时响应。 The method receives a SimpleChanges object of current and previous property values.该方法接收当前和以前的属性值的 SimpleChanges object。 Note that this happens very frequently, so any operation you perform here impacts performance significantly.请注意,这种情况经常发生,因此您在此处执行的任何操作都会显着影响性能。

  1. ngOnInit() ngOnInit()

Called once, after the first ngOnChanges().在第一个 ngOnChanges() 之后调用一次。

Initialize the directive or component after Angular first displays the data-bound properties and sets the directive or component's input properties. Angular首先显示数据绑定属性并设置指令或组件的输入属性后初始化指令或组件。

  1. ngDoCheck() ngDoCheck()

Called immediately after ngOnChanges() on every change detection run, and immediately after ngOnInit() on the first run.在每次更改检测运行时在 ngOnChanges() 之后立即调用,在第一次运行时在 ngOnInit() 之后立即调用。

Detect and act upon changes that Angular can't or won't detect on its own.检测 Angular 无法或不会自行检测到的变化并采取行动。

  1. ngAfterContentInit() ngAfterContentInit()

Called once after the first ngDoCheck().在第一个 ngDoCheck() 之后调用一次。

Respond after Angular projects external content into the component's view, or into the view that a directive is in.在 Angular 将外部内容投影到组件的视图或指令所在的视图后响应。

  1. ngAfterContentChecked() ngAfterContentChecked()

Called after ngAfterContentInit() and every subsequent ngDoCheck().在 ngAfterContentInit() 和每个后续的 ngDoCheck() 之后调用。

Respond after Angular checks the content projected into the directive or component. Angular 检查投影到指令或组件中的内容后响应。

  1. ngAfterViewInit() ngAfterViewInit()

Called once after the first ngAfterContentChecked().在第一个 ngAfterContentChecked() 之后调用一次。

Respond after Angular initializes the component's views and child views, or the view that contains the directive. Angular 初始化组件的视图和子视图,或包含指令的视图后响应。

  1. ngAfterViewChecked() ngAfterViewChecked()

Called after the ngAfterViewInit() and every subsequent ngAfterContentChecked().在 ngAfterViewInit() 和每个后续的 ngAfterContentChecked() 之后调用。

Respond after Angular checks the component's views and child views, or the view that contains the directive.在 Angular 检查组件的视图和子视图,或包含指令的视图后响应。

  1. ngOnDestroy() ngOnDestroy()

Called immediately before Angular destroys the directive or component.在 Angular 破坏指令或组件之前立即调用。

Cleanup just before Angular destroys the directive or component.在 Angular 破坏指令或组件之前进行清理。 Unsubscribe Observables and detach event handlers to avoid memory leaks.取消订阅 Observables 并分离事件处理程序以避免 memory 泄漏。

Visually something like this:视觉上是这样的:

在此处输入图像描述

So you should put ViewChild assignment in ngAfterViewInit() and the ContentChild assignment you should put in ngAfterContentInit() lifecycle hook.因此,您应该将 ViewChild 分配放在 ngAfterViewInit() 中,并将 ContentChild 分配放在 ngAfterContentInit() 生命周期挂钩中。

ngAfterContentInit() {
    this.headerLogoMiniComponent = 'something';
}

ngAfterViewInit() {
    this.templateRef = 'something';
}

First of all This is actually a warning rather than an error.首先,这实际上是一个警告而不是错误。

ExpressionChangedAfterItHasBeenCheckedError is thrown when an expression in your HTML has changed after Angular has checked it.当 HTML 中的表达式在 Angular 检查后发生更改时,将引发 ExpressionChangedAfterItHasBeenCheckedError。 In DevMode change detection adds an additional turn after every regular change detection run, to check if the model has changed.DevMode 中,更改检测在每次常规更改检测运行后添加一个额外的回合,以检查 model 是否已更改。 This error is only thrown in develop mode and it is often a sign that you should consider refactoring your code, as Angular warns you that this change in your expression will not be picked up when enabling production mode..!此错误仅在开发模式下引发,这通常表明您应该考虑重构代码,因为 Angular 警告您在启用生产模式时不会拾取您的表达式中的这种更改..!

One of the main root cause for this type of warnings is, you are executing some code in AfterViewInit which often happens when working with ViewChild , as it is undefined until AfterViewInit is called.此类警告的主要原因之一是,您正在 AfterViewInit 中执行一些代码,这在使用ViewChild时经常发生,因为在调用 AfterViewInit之前它是未定义的。

Check the below link for a detailed explanation and better understanding of ExpressionChangedAfterItHasBeenCheckedError ..检查下面的链接以获得对ExpressionChangedAfterItHasBeenCheckedError的详细解释和更好的理解。

ExpressionChangedAfterItHasBeenCheckedError Explained ExpressionChangedAfterItHasBeenCheckedError 解释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM