简体   繁体   English

Angular Portal cdkPortal 指令 throw Expression Changed 错误

[英]Angular Portal cdkPortal directive throw Expression Changed error

I use Angular Material Portal to move element in another place.我使用 Angular Material Portal 将元素移动到另一个地方。

I use cdkPortal and cdkPortalOutlet .我使用cdkPortalcdkPortalOutlet

I don't understand why angular throw expression changed in this super simple example我不明白为什么 angular 抛出表达式在这个超级简单的例子中发生了变化

import { Component, ViewChild } from '@angular/core';
import { CdkPortal } from '@angular/cdk/portal';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  @ViewChild(CdkPortal, { static: false }) portal: CdkPortal
}

Check code here: https://stackblitz.com/edit/angular-f6sb21在此处检查代码: https://stackblitz.com/edit/angular-f6sb21

open console to see error:打开控制台查看错误:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'portal: undefined'. Current value: 'portal: [object Object]'

You are referencing the same object to the cdkPortalOutlet .您将相同的 object 引用到cdkPortalOutlet You actually need another ng-template with its ViewChild您实际上需要另一个带有ViewChild ng-template

<ng-template #templatePortalContent>Hello, this is a template portal</ng-template>

and in the ts file:并在 ts 文件中:

// This is the reference for the ng-template that we added
@ViewChild("templatePortalContent", { static: false }) templatePortalContent: TemplateRef<any>;
// This is the variable that will hold the new template
templatePortal;

constructor(private _viewContainerRef: ViewContainerRef, private cdr: ChangeDetectorRef) {}

ngAfterViewInit() {
  this.templatePortal = new TemplatePortal(
    this.templatePortalContent,
    this._viewContainerRef
  );
    this.cdr.detectChanges();
}

This is for the TemplatePortal.这是为 TemplatePortal 准备的。

If you need a ComponentPortal, it means if you have already a component, then you will need to create the portal and assign it in the cdkPortalOutlet instead of templatePortal variable.如果您需要一个 ComponentPortal,这意味着如果您已经有一个组件,那么您将需要创建门户并在cdkPortalOutlet而不是templatePortal变量中分配它。

this.componentPortal = new ComponentPortal(ComponentPortalExample);

and

<ng-template [cdkPortalOutlet]="componentPortal"></ng-template>

You can check here for more info:您可以在此处查看更多信息:

Here is the demo .这是演示

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

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