Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockoutjs bind mouseover or Jquery

I have this code in jquery. How would I write this in knockout with binding. Or is it better to have it in jquery. Is there a smart way to know when to write it in binding or in jquery? This is more viewstuff so maybe it should be in Jquery ?

$("body").on("mouseover mouseout", '.hoverItem', function () {
    $(this).toggleClass('k-state-selected');
});
like image 774
user1199595 Avatar asked Feb 10 '12 11:02

user1199595


1 Answers

If the toggling of this class doesn't really need to connect to the data in your view model, then there is really no reason that you couldn't do what you are doing now.

Here is a sample of how to do it with the default bindings:

view:

<ul data-bind="foreach: items">
    <li data-bind="text: name, event: { mouseover: toggle, mouseout: toggle }, css: { hover: selected }"></li>
</ul>

view model code:

var Item = function(name) {
    this.name = ko.observable(name);
    this.selected = ko.observable(false);
    this.toggle = function() {
       this.selected(!this.selected());   
    }
};

var viewModel = {
    items: ko.observableArray([
        new Item("one"),
        new Item("two"),
        new Item("three")
    ])
};

ko.applyBindings(viewModel);

With custom bindings you could even reduce it down to:

<ul data-bind="foreach: items">
    <li data-bind="text: name, hoverToggle: 'hover'"></li>
</ul>

view model:

ko.bindingHandlers.hoverToggle = {
    update: function(element, valueAccessor) {
       var css = valueAccessor();

        ko.utils.registerEventHandler(element, "mouseover", function() {
            ko.utils.toggleDomNodeCssClass(element, ko.utils.unwrapObservable(css), true);
        });  

        ko.utils.registerEventHandler(element, "mouseout", function() {
            ko.utils.toggleDomNodeCssClass(element, ko.utils.unwrapObservable(css), false);
        });      
    } 
};

var Item = function(name) {
    this.name = ko.observable(name);
};

var viewModel = {
    items: ko.observableArray([
        new Item("one"),
        new Item("two"),
        new Item("three")
    ])
};

ko.applyBindings(viewModel);

You could even get more sophisticated and have it work in a delegated fashion like on by putting the binding at a higher level and applying the toggle based on a selector.

As far as a rule of thumb, I think that it is up to the developer whether they want to use wire up code or do it declaratively when the functionality does not require data from the view model. In your case, probably good enough to stick with on until it requires data from your view model.

like image 136
RP Niemeyer Avatar answered Sep 22 '22 14:09

RP Niemeyer