Corrado's Blog 2.0

Online thoughts of a technology funatic

MvvmStack for WinJS: Application Resuming support

I’ve checked in a new version of MvvmStack that has a small tweak and a “new” feature, let’s start with the latter:

Resuming support

Sometimes you need to be informed when app resumes, an example is because you want to download some fresh data if app has been suspended longer than a certain amount of time.

With MvvmStack all you need to do to is to add a onAppResuming method to your services and/or ViewModels, something like: (see sectionViewModel.js on sample code)

onAppResuming: function () {
            console.log("SectionViewModel notified that app has been resumed.")
        }

And it will be invoked each time app resumes.

The ‘tweak’ regards the way you add new  ViewModels, in this post, on Closing section i mention:

“3- Add a new property “pagenameViewModel” to ViewModelLocator’s  viewModels object“ 

starting from this version the step is no longer required Smile

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)