[英]Angular and SVG: how to dynamically load SVG components?
在我正在開發的應用程序中,我有一個命令列表(GC->circle、GB->box、GE->ellipse 等)。 我必須在 SVG 中渲染它們。
我遵循了https://angular.io/guide/dynamic-component-loader指南,但我對 SVG 有一些遺漏。
我為每個命令准備了一個組件(這聽起來很愚蠢,因為除了模板之外代碼都相同):
@Component({
selector: '[app-gc]',
template: '<svg:circle [attr.r]="command.diameter/2" [attr.stroke]="command.borderColor" fill="#000" [attr.stroke-width]="command.borderThickness" />'
})
export class GCComponent implements OnInit, SVGComponent {
@Input('[command]') command: ZPL2.GraphicShapeBase;
constructor() { }
}
我加載渲染命令的組件如下所示:
@Component({
selector: '[draggableSVGItem]',
template: '<svg:g svg-host/>'
})
export class DraggableSvgItemComponent implements OnInit {
x: number = 0;
y: number = 0;
command: ZPL2.GraphicShapeBase;
@Input()
set draggableSVGItem(graphicCommand: ZPL2.GraphicShapeBase) {
this.command = graphicCommand;
this.x = graphicCommand.x;
this.y = graphicCommand.y;
}
constructor() { }
ngOnInit() {
// Get the appropriate component for the command
var componentType = null;
if (this.command instanceof ZPL2.GC) {
componentType = GCComponent;
}
if (this.command instanceof ZPL2.GB) {
componentType = GBComponent;
}
if (this.command instanceof ZPL2.GE) {
componentType = GEComponent;
}
// Get the component factory
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
// Clear the host view
let viewContainerRef = this.svgHost.viewContainerRef;
viewContainerRef.clear();
// Dynamically create the component and set its command as the current one
let componentRef = viewContainerRef.createComponent(componentFactory,);
(<SVGComponent>componentRef.instance).command = this.command;
}
}
一切都幾乎完美無缺。 我遇到的問題是組件創建將 SVG 元素封裝到 DIV 中,因此輸出為空白:
我是 Angular 的新手,你有什么建議可以擺脫那個 DIV 並使代碼更簡單嗎?
我按照此鏈接中的示例解決了它: https : //www.chrisjmendez.com/2017/06/17/angular-dynamically-inserting-svg-into-an-element/
通過綁定元素的 innerHTML 屬性,我可以根據命令類類型設置不同的 SVG 內容:
模板: <svg:g [innerHTML]="svg"/>
ngOnInit() {
// Get the appropriate component for the command
var html = ``;
if (this.command instanceof ZPL2.GC) {
html = `<circle r="` + this.command.diameter / 2 + `" stroke="` + this.command.borderColor + `" fill="#000" stroke-width="` + this.command.borderThickness + `" />`;
}
if (this.command instanceof ...
this.svg = this.sanitizer.bypassSecurityTrustHtml(html);
}
這樣我就不需要為每個命令創建一個組件。 每個命令都可以有自己的 getHTML() 方法。
缺點是我沒有綁定命令的屬性,對吧?
我的動態加載 svg 文件的解決方案(對於同一組件):
在 .html 模板中(我使用下拉列表實現了它,但在這里我剪切了示例代碼):
<object *ngIf="currentSVG" type="image/svg+xml" [data]="SVGFile"></object>
在 .ts 文件中:
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
//component and class definition
SVGFile: SafeUrl;
currentSVG: string;
constructor(protected sanitizer: DomSanitizer) { ... }
//your code
this.currentSVG = True;
this.SVGFile = this.sanitizer.bypassSecurityTrustResourceUrl('<your SVG file path>');
注意:SVG 文件應位於資產目錄中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.