Suppose I have knockout.js template like this:
I have done something like this in the past:
ko.bindingHandlers.uniqueId = {
init: function(element) {
element.id = ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);
},
counter: 0,
prefix: "unique"
};
ko.bindingHandlers.uniqueFor = {
init: function(element, valueAccessor) {
var after = ko.bindingHandlers.uniqueId.counter + (ko.utils.unwrapObservable(valueAccessor()) === "after" ? 0 : 1);
element.setAttribute("for", ko.bindingHandlers.uniqueId.prefix + after);
}
};
You would use them like:
-
So, it just keeps state on the binding itself incrementing ko.bindingHandlers.uniqueId.counter. Then, the uniqueFor binding just needs to know whether it is before or after the field to know how to get the correct id.
Sample here: http://jsfiddle.net/rniemeyer/8KJD3/
If your labels were not near their fields (multiple inputs bound before each label perhaps in separate rows of a table), then you would need to look at a different strategy.