繁体   English   中英

Angular + SVG:如何从字符串动态加载模板

[英]Angular + SVG: how to dynamically load template from string

在 Angular 中,可以使用 SVG 作为组件模板。 我想知道是否有办法将 SVG 内容(从服务器加载的字符串)转换为组件模板,包括将一些属性绑定到它的可能性(即<tspan [attr.color]="textColor"...>{{myText}}</tspan> )。

我做了一些测试,我得到的只是加载和渲染 SVG 内容,但绑定不起作用。 相反,它们被呈现为字符串。

我知道如果将 SVG 内容放在一个文件中并在组件的templateUrl设置中引用它,它就可以工作。 例如:

...
@Component({
   templateUrl: './content.svg'
})
export class MyComponent {
   ...
}
...

我已经测试过了。 但是,我需要从服务器加载 SVG(它不能是 static 文件或硬编码在源代码中)。

谁能帮我?

更新

只是为了澄清一点......

考虑以下组件:

@Component({
    selector: 'my-component',
    template: `<div [innerHtml]="mySvg"></div>`
})
export class MyComponent {
    textColor: string;
    myText: string;
    mySvg: string;

    constructor() {
        this.textColor = '#ff0000';
        this.myText = 'Just testing';
    }

    loadSvg() {
        // here goes some logic to request the SVG string from server
        // ...
       this.mySvg = response;
    }
}

现在,考虑服务器返回以下字符串:

<svg>
    <tspan [attr.color]="textColor">{{myText}}</tspan>
</svg>

我希望能够渲染 SVG 并且插值也能正常工作(可以更改文本和颜色)。

可能吗?

如果您坚持使用本机标准 Javascript 模板文字符号: ${x}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

 `string ${property} string string ${property} string` 

您可以创建一个标记模板 function为您完成所有属性值的替换

这里的模板字符串innerHTML ,属性作为属性

当您编写自己的模板语法(或使用第 3 方)时,您将不得不添加更多样板代码或库来解析该字符串

 <svg-from-template cx="30" cy="30"> <rect x='0' y='0' width='100%' height='100%' fill='${bgcolor}'></rect> <circle cx='${cx}' cy='${cy}' r='10%' fill='${fill}'></circle> </svg-from-template> <svg-from-template bgcolor="lightgreen" cx="70" cy="70" fill="green"> <rect x='0' y='0' width='100%' height='100%' fill='${bgcolor}'></rect> <circle cx='${cx}' cy='${cy}' r='20%' fill='${fill}'></circle> </svg-from-template> <script> customElements.define( "svg-from-template", class extends HTMLElement { connectedCallback() { function parseTemplate(templateString, templateData = {}) { return new Function( // create Function AND return the executed function result "templateProps", [ "let f = ( " + Object.keys(templateData).join(",") + " ) =>", "`" + templateString + "`", "return f(...Object.values(templateProps))", ].join("\n") )(templateData); // execute tagged template function } setTimeout(() => { // wait till all innerHTML is parsed by the Browser let templateData = [...this.attributes].reduce((acc, attr) => { acc[attr.name] = attr.value; // copy element attributes to {} object return acc; }, { /*default object*/ bgcolor: 'pink', fill: 'red' }); let templateString = this.innerHTML; // OR read from file/server/universe this.innerHTML = "<svg mlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>" + parseTemplate(templateString, templateData) + "</svg>"; }); } } ); </script> <style> svg { width: 180px; /* SO snippet window height */ } </style>

暂无
暂无

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

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