Organizing your WinJS Metro code into namespaces

I have been struggling with namespacing since I started with WinJS. Not sure why, just can never get the Magical Rites correct. I think is has to do with when to add the Feral Cat Whiskers.

Anyway, here is a list of how I made it work for a simple reference project.

1) Add a base.js file to your /js directory. Populate it with a namespace declaration. DO NOT FORGET the closing parens.

(function () {
    WinJS.Namespace.define('MyApp', {});
})();

2) Add a settings.js file to the /ja folder (for example). Populate it with a method to share with the namespace.

(function () {
    function getSettings() {
        var settings = "D";
    }
    WinJS.Namespace.defineWithParent(MyApp, 'Settings', {
        getSettings: getSettings,
    });
})();

3) In the default.html file, add a reference to the two new files.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Namespace</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script>

    <!-- Namespace references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
    <script type="text/javascript" src="js/base.js"></script>
    <script type="text/javascript" src="js/settings.js"></script>
</head>
<body>
    <p>Content goes here</p>
</body>
</html>

4) In default.js, call MyApp.Settings.getSettings() in the onactivated event. It's the bold line below.

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                MyApp.Settings.getSettings();
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };
    
    app.start();
})();

That's it. All there is too it. Everything else is gravy. At least this will give me something to go back and look at when I forget how to do it.

Make sure to get my new Windows 8 Programming with HTML5 For Dummies book when it comes out.

Comments (2) -

Josh
7/30/2012 6:53:05 AM #

While this works, namespaces do merge and we support dots in Namespace define so the recommended way of doing this would be:

WinJS.Namespace.define("MyApp.Settings", {
    getSettings: getSettings
});

On the WinJS team we went through a period where we mostly defined namespaced functions directly in the namespace definition like:

WinJS.Namespace.define("MyApp.Settings", {
    getSettings: function () {
        var settings = "D";
    }
});

However we found a number of cases where we screwed up and referred to sibling namespace members using 'this.' which is incorrect for namespace members since they may be disconnected from the namespace and called independently without the caller having to  bind the 'this' argument. So we moved to the pattern you see in (most) of WinJS today and the pattern in your blog where the functions are defined and then referenced in the namespace definition which gives the developer the right intuition that namespaces are simply an organization scheme not a runtime visible semantic of a function.

-josh

Bill Sempf
7/31/2012 6:15:58 AM #

Awesome comment, Josh. I didn't know that dot notation was supported, although I guess I coulda looked at the WinJS code to see. Thanks for taking the time to point it out!

Comments are closed

Bill Sempf

Husband. Father. Pentester. Secure software composer. Brewer. Lockpicker. Ninja. Insurrectionist. Lumberjack. All words that have been used to describe me recently. I help people write more secure software.

profile for Bill Sempf on Stack Exchange, a network of free, community-driven Q&A sites

MonthList