问题
I'm iterating over an object using dom-repeat, and want to reference different icons from an SVG sprite sheet with each iteration. To add an icon, I'm trying to use the <use xlink:href="sprite.svg#id"> method, mixed with Polymer's computed bindings. Here's the code inside the dom-repeat block:
<template is='dom-repeat' items="{{currentPlan.functionalities}}">
<div class="resourceRow rowParent">
<div class="functionIconContainer columnParent">
<svg><use xlink:href$="{{ _getIconURL(item.id) }}"/></svg>
</div>
</div>
</template>
& the JS logic:
_getIconURL: function(iconID){
var url = "sprite.svg#" + iconID;
return url;
}
This code outputs what I want it to, as far as I can see in Dev Tools, but still the icon doesn't show up. For reference, here's an example of what is written to the DOM:
<svg class="style-scope">
<use class="style-scope" xlink:href="sprite.svg#id"/>
</svg>
Is this a bug or my misunderstanding?
回答1:
I had exactly the same problem before and ended up using iron-iconset-svg (https://elements.polymer-project.org/elements/iron-icons?active=iron-iconset-svg), which in my opinion provides a cleaner/easier solution. Its simply a wrapper for your SVG sprite sheet, so you define your icons almost the same way and use them with iron-icon.
Defining a custom iconset (put it directly into the page or wrap it inside an element + set a name that describes the icons, here: 'your-iconset-name')
<iron-iconset-svg name="your-iconset-name" size="24">
<svg>
<defs>
<g id="your-icon-name">
<rect x="12" y="0" width="12" height="24" />
<circle cx="12" cy="12" r="12" />
</g>
</defs>
</svg>
</iron-iconset-svg>
If you wrap them, lets say in 'your-custom-iconset', you can include the iconset like this:
<your-custom-iconset></your-custom-iconset>
Using icons
When you need an icon you just include iron-icons (https://elements.polymer-project.org/elements/iron-icons) and place it like this:
<iron-icon icon="your-iconset-name:your-icon-name"></iron-icon>
You can then give it a class to apply styling and don't need to use 'fill' for its color, just use 'color'.
Applied to your example:
<template is='dom-repeat' items="{{currentPlan.functionalities}}">
<div class="resourceRow rowParent">
<div class="functionIconContainer columnParent">
<iron-icon icon$="your-iconset-name:{{item.id}}"></iron-icon>
</div>
</div>
</template>
回答2:
Ok, not sure if this really counts as an answer, but it fixes my immediate problem. I've attached an on-dom-change event handler to the dom-repeat block, which gets called on well, DOM changes.
Then I loop through each icon container and set its innerHTML to itself. I don't know what it does, but it somehow forces a re-evaluation of that part of the DOM, causing my icons to show up. It's the simplest of code:
_forceRedraw: function(){
var functionIcons = document.querySelectorAll('div.functionIconContainer');
_.each(functionIcons, function(iconContainer){
iconContainer.innerHTML = iconContainer.innerHTML;
})
}
'Lo, it works!
回答3:
A workaround is to add the attribute statically in addition to the binding
<svg><use xlink:href="" xlink:href$="{{ _getIconURL(item.id) }}"/></svg>
Polymer has issues with creating the attribute, updating it works fine though.
回答4:
This is a duplicate of: Polymer (1.0) - dynamic use xlink:href$ inside template not working properly
This is a Polymer bug, filed as issue #3060.
来源:https://stackoverflow.com/questions/34434881/svg-use-tags-within-polymer-dom-repeat