Let's consider a view model using knockout like that:
var data = [{ id: 1, name: "John Doe" }, { id: 2, name: ""}, { id: 3, name: "Peter Parker"}];
var viewModel = {
items: ko.observableArray(data)
};
viewModel.showName = function (name) {
console.log(this);
return name && name.length > 0;
};
viewModel.removePerson = function () {
console.log(this);
};
ko.applyBindings(viewModel);
With this View:
<ul data-bind="foreach: items">
<li><span data-bind="text: id"></span>
<span data-bind="visible: $root.showName(name)">Yes! show the name</span>
<a href="#" data-bind="click: $root.removePerson">Remove</a>
</li>
</ul>
You can see it in action here: http://jsfiddle.net/SmW35/8/
In this case, when someone clicks the "Remove" link, and KO calls the showName function, the object "this" inside the function, it's an object with the current item, for example, if I click "remove" in the item 2, "this" is {id: 2, name: ""} However, when KO is binding the "visible" and calls the showName function, the "this" object doesn't contains the current item, and you have to pass "name" to the function (or you could use the $data).
So, I have 2 questions:
- There's a way to call the showName function from the View, without passing the name or $data (similar behaviour than with the Remove link)
- If not, there's something wrong do it that way? I have an interesting discussion with a workmate that thinks that is not right do it that way because you are sending data from the View ($root.showName(name)), and then this is not a "pure" MVVM pattern. He's proposing create a custom KO binding to achieve the functionality. In my opinion is killing flies with a tank, but I'm very curious to know if there's a different way or you also think I'm not doing a pure MVVM pattern with my code.