Corrado's Blog 2.0

Online thoughts of a technology funatic

MvvmStack for WinJS: Command support

A Command represents an abstraction over an action, the command can also indicate whether the action is available or not and, normally, UI elements tied to a command disables themselves when command is not available, if you’re new to MVVM’s commanding I recommend this article.

While more a .NET concept than a Mvvm pattern core feature, i decided to add support for it with latest checkin since its wide popularity and to keep the stack aligned with other .NET based libraries.

In  .NET a Command depends upon the ICommand interface and it is generally implemented by generic classes like RelayCommand or DelegateCommand, for MvvmStack I’ve used a simpler implementation available in relayCommand.js

(function (winjs) {
    "use strict";

    var RelayCommand = WinJS.Class.define(function(execute) {
        this.execute = execute;
        this.execute.supportedForProcessing = true;
        this.canExecute = winjs.Binding.as({value:true});
    },
        {
            execute: null,
            canExecute: null
        });

    winjs.Namespace.define("MvvmStack", {
        RelayCommand: RelayCommand
    });

})(WinJS)

To use it all you need is to expose instances of RelayCommand from your viewmodels, sample code exposes them in sectionViewModel.js

firstCommand: new mvvmStack.RelayCommand(function (element) {
            this.currentPage.value = 0;
            this.firstCommand.canExecute.value = false;
            this.lastCommand.canExecute.value = true;
        }),
        lastCommand: new mvvmStack.RelayCommand(function (element) {
            this.currentPage.value = this.images.length - 1;
            this.firstCommand.canExecute.value = true;
            this.lastCommand.canExecute.value = false;
        }),

then we wire the commands with application bar commands in section.html page

<div data-win-control="WinJS.UI.AppBar">
            <button
                data-win-control="WinJS.UI.AppBarCommand"
                data-win-bind="onclick:firstCommand Binding.Mode.command"
                data-win-options="{icon:'home', id:'', label:'Home', section:'global', type:'button'}">
            </button>
            <button
                data-win-control="WinJS.UI.AppBarCommand"
                data-win-bind="onclick:lastCommand Binding.Mode.command"
                data-win-options="{icon:'next', id:'', label:'Last', section:'global', type:'button'}">
            </button>
        </div>

In order to keep button state in sync with commands availability we use a new Binding.Mode.command initializer, also note how click event binds to command and not to its execute function.

As usual the binding initializer is defined inside binding-extensions.js, you can update it in case you need to handle other enable/disable scenarios.

Binding.Mode.command automatically adds a mvvm-disabled class to invoking element (app bar buttons in our case) so that you can use a css class to change the look of the control while in disabled state.

To see commands in action, run the sample, navigate to section page and click application bar’s buttons or navigate through images to see how buttons follow current’s image position.

Hope you like it Smile

PS: In order to simplify dev life I’ve added a watch function to viewModelBase that allows to invoke a function when an observable property changes (just a simple wrapper around bind function indeed Winking smile)

No Responses to “MvvmStack for WinJS: Command support”

RSS feed for comments on this post. TrackBack URL

Leave a Response