[英]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.