Reputation: 776
I have made an icon custom binding that works fine if I do something like this
<div data-bind="icon: 'icon-name'"></div>
I want the icon to be variable so in my view model I have:
var element = {
icon: ko.computed(function() {
return 'icon-' + iconType();
}
}
In my html I have:
<div data-bind="icon: ko.utils.unwrapObservable(icon)"></div>
But this is not working. Note that if I insert another div before like this:
<div data-bind="text: ko.utils.unwrapObservable(icon)"></div>
I get a div with exactly the name of the icon that I wanted, lets say 'icon-1'.
So my guess is that unwrapObservable does not give me the text in the format I need.
Any ideas how to fix this?
The icon binding:
ko.bindingHandlers.icon = {
init: function(element, valueAccessor) {
var icon = ko.unwrap(valueAccessor());
$(element).html(icons[icon]);
}
}
Upvotes: 0
Views: 1206
Reputation: 32202
Instead of init
, you need to handle update
, for when the value changes, which is what's happening with the computed:
ko.bindingHandlers.icon = {
update: function(element, valueAccessor) {
var icon = ko.unwrap(valueAccessor());
$(element).html(icons[icon]);
}
}
You should then be able to bind as normal, without needing to upwrap the value within the binding:
<div data-bind="icon: icon"></div>
With regards to init
, the documentation says:
Knockout will call your init function once for each DOM element that you use the binding on. There are two main uses for init:
- To set any initial state for the DOM element
- To register any event handlers so that, for example, when the user clicks on or modifies the DOM element, you can change the state of the associated observable
IE it's not necessary here, you can do everything you need through update
.
Upvotes: 2