画布未显示在 Angular 的 ng 模板中



我正在使用Angular 8

我有一个canvas元素,它必须显示在父组件内的不同子组件中,但其上的数据应该是相同的。

为了解决这种情况,我在子组件中使用了ng-content,例如

组件A组件 B包含 HTML

<div class="child">
<ng-content select=["canvasPreview]"></ng-content>
</div>

组件

<mat-horizontal-stepper labelPosition="bottom" #stepper (selectionChange)="onSelectionChange($event)">
<mat-step>
<ng-template matStepLabel>Upload Image</ng-template>
<app-upload-background-image
[(previewImage)]="previewImage"
(previewImageChange)="onPreviewImageChange($event)">
</app-upload-background-image>
</mat-step>
<mat-step>
<ng-template matStepLabel>Place Canvas A</ng-template>
<app-a>
<div canvasPreview *ngTemplateOutlet="canvas"></div>
</app-a>
</mat-step>
<mat-step>
<ng-template matStepLabel>Design Canvas B</ng-template>
<app-b>
<div canvasPreview *ngTemplateOutlet="canvas"></div>
</app-b>
</mat-step>
</mat-horizontal-stepper>
<ng-template #canvas>
<app-canvas-child></app-canvas-child>
</ng-template>

app-canvas-child组件具有canvas元素

canvas-child.component.html

<div class="title">Canvas Success</div>
<canvas height="400" width="500">

但在组件中,它显示app-canvas-child组件的画布成功标题,但画布区域为空白。直接在父组件中使用相同(在 ng 模板之外(工作正常并显示画布。

我认为会出现这个问题,因为内容投影的角度克隆元素。如果画布节点被克隆,则其上下文将丢失。在您的情况下,您必须提供父组件的画布上下文。

堆栈闪电战:https://stackblitz.com/edit/canvas-cloning-angular

应用组件:

import { Component, ViewChild, TemplateRef,ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
@ViewChild('c',{static:false}) canvas;
ctx
constructor(private cdRef:ChangeDetectorRef) {
}
ngAfterViewInit() {
const c = this.canvas.nativeElement
this.ctx = c.getContext("2d");
this.ctx.fillStyle = "#FF0000";
this.ctx.fillRect(0, 0, 150, 75);
this.cdRef.detectChanges();
}
change() {
console.log("ADS")
this.ctx.fillStyle = "#FFff00";
this.ctx.fillRect(0, 0, 150, 75);
this.canvas = { ... this.canvas }
}
}

AppComponent-tpl:

<h1>In Parent:</h1>
<canvas #c width="200" height="100"></canvas>
<child [canvasAAA]="canvas"></child>
<child [canvasAAA]="canvas"></child>
<child [canvasAAA]="canvas"></child>
<button (click)="change()">change</button>

子组件:

import { Component, Input, ViewChild } from '@angular/core';
@Component({
selector: 'child',
template: `<h2>In Child</h2><canvas #c width="200" height="100"></canvas><hr>`,
})
export class ChildComponent  {
@Input() canvasAAA;
@ViewChild('c',{static:false}) c;
ngOnChanges(){
if(!this.c || !this.canvasAAA){
return;
}
console.log(this.canvasAAA)
var context = this.c.nativeElement.getContext('2d');
//set dimensions
this.c.nativeElement.width = this.canvasAAA.nativeElement.width;
this.c.nativeElement.height = this.canvasAAA.nativeElement.height;
//apply the old canvas to the new one
context.drawImage(this.canvasAAA.nativeElement, 0, 0);
}
}

我认为你必须使用ngProjectAs. 我写了一篇关于它的文章。

你应该像这样修改你的代码:

<mat-step>
<ng-template matStepLabel>Place Canvas A</ng-template>
<app-a>
<div ngProjectAs="[canvasPreview]" *ngTemplateOutlet="canvas"></div>
</app-a>
</mat-step>
<mat-step>
<ng-template matStepLabel>Design Canvas B</ng-template>
<app-b>
<div ngProjectAs="[canvasPreview]" *ngTemplateOutlet="canvas"></div>
</app-b>
</mat-step>

相关内容

  • 没有找到相关文章

最新更新