Reputation: 678
I've got a knockout viewModel which looks like this:
function myViewModel() {
this.update = function() {
...
}
...
}
And a bindingHandler which looks like this:
ko.bindingHandlers.myBindingHandler = {
init: function(element, valueAccessor, allBindings, viewModel) {
function manipulateDom(element) {
...
}
}
}
I want myViewModel to call manipulateDom whenever the update method is called.
I could do this using a callback set in the bindingHandler:
function myViewModel() {
this.update = function() {
...
this.myBindingHandlerCallback();
}
...
}
ko.bindingHandlers.myBindingHandler = {
init: function(element, valueAccessor, allBindings, viewModel) {
viewModel.myBindingHandlerCallback = manipulateDom.bind(null, element);
}
}
<div data-bind="myBindingHandler: null"></div>
Another idea I had was to use an 'updateCount' observable and subscribing to it in the bindingHandler:
function myViewModel() {
this.updateCount = ko.observable(0);
this.update = function() {
...
this.updateCount(this.updateCount() + 1);
}
...
}
ko.bindingHandlers.myBindingHandler = {
update: function(element) {
manipulateDom(element);
}
}
<div data-bind="myBindingHandler: updateCount"></div>
Both of these solutions feel fragile and messy. What is the 'knockout' way of approaching this sort of problem? Should I just be manipulating the DOM from within the viewModel?
I should add that the manipulateDom function has a lot of logic which isn't applicable in a knockout fashion (measuring window heights, measuring DIV heights etc...)
Thanks!
Upvotes: 0
Views: 351
Reputation: 241
Second approach (with counter) is much better, because the ViewModel shouldn't override and change ViewModel's behavior by overriding its properties.
Instead of having counter, if your update method does some changes to other observable properties I would create a computed property which will subscribe to the current state of the ViewModel and automatically invoke your DOM manipulation binding if you would pass it as a binding parameter, no need to increment counter or any other flag then.
Upvotes: 1