In a sense, your colleague has a point. I personally would not create a custom binding to handle this (throughout the subjective note, custom bindings are more suitable if there is a special way of communication between the view and presentation model, see this post for a great explanation when to use them).
On the side of the note, if we examine the custom binding option, I think you can do something like a textIfNotEmpty binding handler that combines text and visible in one. On the other hand, if the functionality of showName remains as simple as you, you can also:
<span data-bind="visible: !!name, text: name"></span>
In any case, I would prefer the following ...
The main problem is IMO, that the view model violates the principle of shared responsibility: the showName functionality should be responsible for representing the model representing the element.
var Item = function(data) { var self = this; self.id = data.id; self.name = ko.observable(data.name);
Now you can easily link like this:
<ul data-bind="foreach: items"> <li><span data-bind="text: id"></span> <span data-bind="visible: showName">Yes! show the name</span> <a href="#" data-bind="click: $root.removePerson">Remove</a> </li> </ul>
Which also allows you to rewrite removePerson to this:
viewModel.removePerson = function (person) { console.log(person); };
This requires you to do a little extra work to build an observable array, but it's worth it because it clearly shares all the problems. This can be done as follows:
var viewModel = { items: ko.observableArray(data.map(function(item) { return new Item(item); })) };
See this script for a demonstration of the above.
Jeroen
source share