I can modify xlink:href
through javascript and jquery just fine but modifying just the dom's xlink:href
through the knockout attr
binding does not work.
This is my svg definition
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">
<defs>
<symbol id="icon-home" viewBox="0 0 32 32">
<path class="path1" d="M32 18.451l-16-12.42-16 12.42v-5.064l16-12.42 16 12.42zM28 18v12h-8v-8h-8v8h-8v-12l12-9z"></path>
</symbol>
</defs>
This is inserted at the top of the body
Then use knockout with html and the property icon
on my view model
<svg class="svg-icon">
<use id="myuse" data-bind="attr: {'xlink:href': icon }"></use>
</svg>
I am sure icon is returning correctly because I get the following rendered output
<svg class="svg-icon">
<use data-bind="attr: {'xlink:href': icon }" xlink:href="#icon-home"></use>
</svg>
Which is correct, but nothing shows up. Does anyone have a working solution to this with knockout?
As it seems, SVG will not update on DOM's modification.
So basically what you need to do is remove the SVG, update the fields, and add the SVG markup again.
This can be emulated with an if
binding:
<!-- ko if: showSvg -->
<svg class="svg-icon">
<use data-bind="attr: {'xlink:href': icon }"></use>
</svg>
<!-- /ko -->
When showSvg
becomes false
, your SVG will be removed from the DOM, and added again when it becomes true
.
You would do:
myModel.showSvg(false);
myModel.icon("whatever");
myModel.showSvg(true);
Or more ko compliant, use a writeable computed to encapsulate this behaviour:
myModel.iconComp = ko.computed({
read: myModel.icon,
write: function (value) {
myModel.showSvg(false);
myModel.icon(value);
myModel.showSvg(true);
},
owner: this
});
And use iconComp
in your markup instead of icon
.
Ok, forget everything I said...
It works if you define your attribute first (tested with last Chrome and IE):
<svg class="svg-icon">
<use data-bind="attr:{ 'xlink:href': icon }" xlink:href=''></use>
<!-- Add the attr you want to bind to, set it blank like this for example-->
</svg>
Then do your normal binding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With