Improving on KoLite

Categories: JavaScript

Tags: Knockoutjs, KoLite

In my posts on creating a dynamic menu system, I used KoLite commands to represent what gets invoked when clicking on a menu item.  KoLite adds a command abstraction to Knockout that cleanly encapsulates the execution of a command and the status of a command (with the canExecute() computed, you can disable UI widgets that cannot be executed in the current state).

There was just one thing missing from the command that I wanted: the ability to tell if a command is toggled or latched.  Latching a command means that the command is “on” and all UI elements bound to this can update their state (for example, a menu item in a drop down menu typically has a checkmark or dot placed next to the item to convey that the item is on or toggled).

The concept of latching is very simple to implement.  In knockout.command.js, I added the following code to the ko.command constructor function:

ko.command = function (options) {
    var self = ko.observable(),
        canExecuteDelegate = options.canExecute,
        executeDelegate = options.execute,
        latchedDelegate = options.isLatched; // new

    // new computed; everything else is the same
    self.isLatched = ko.computed(function () {
        return latchedDelegate ? latchedDelegate() : false;
    });
};

This is really simple – it’s just adding a function that delegates to another function you supply when you setup the command.  This function you supply represents the logic required to tell if the command is in a latched state or not.

Here’s an example of how this could be used:

var showStatusBarCmd = ko.command({
    execute: function () {
        showStatusBar(!showStatusBar);
    },
    isLatched: function () {
        return showStatusBar() === true;
    }
});

 

In this example, there’s an observable in the outer scope called showStatusBar that will be used to determine if the status bar in the app is visible.  If the user clicks on a menu item bound to this command, the execute() handler will fire toggling the showStatusBar observable.  The status bar’s visibility is then bound to this value.  Now for latching, the isLatched handler will test to see if showStatusBar is true and will return true if it is.

Now, in the menu system you would probably wire up an element that would show a checkmark or a dot next to the menu item if the command’s latched state is on.  Note that you could have two different UI elements bound to the same command (like a menu item and a toolbar button) and both would be synchronized automatically to changes in the app’s state.

No Comments