locked
AMD loader and WinJS: app.onactivated does not fire

    Question

  • I'm trying to use Dojo's AMD loader with WinJS. This is my default.js:

    require([
        "dojo/ready",
        "dojo/parser",
        "dijit/registry",
        "dojo/dom",
        // non referenced includes
        "dijit/form/Button",
        "dijit/form/DateTextBox"
    ], function (ready, parser, registry, dom) {
    
        ready(function () {
    
            console.log('ready');
    
            WinJS.Binding.optimizeBindingReferences = true;
    
            var app = WinJS.Application;
            var activation = Windows.ApplicationModel.Activation;
    
            app.onactivated = function (args) {
    
                console.log('app.onactivated');
    
                if (args.detail.kind === activation.ActivationKind.launch) {
                    if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                        // TODO: Diese Anwendung wurde neu eingeführt. Die Anwendung
                        // hier initialisieren.
                    } else {
                        // TODO: Diese Anwendung war angehalten und wurde reaktiviert.
                        // Anwendungszustand hier wiederherstellen.
                    }
                        
                    registry.byId('myButton').on('click', function () {
                        dom.byId('greetingOutput').innerHTML = 'Hello ' + registry.byId('myInput').get('value') + ' !';
                    });
    
                }
            };
    
            app.oncheckpoint = function (args) {
                // TODO: Diese Anwendung wird gleich angehalten. Jeden Zustand,
                // der über Anhaltevorgänge hinweg beibehalten muss, hier speichern. Dazu kann das
                // WinJS.Application.sessionState-Objekt verwendet werden, das automatisch
                // über ein Anhalten hinweg gespeichert und wiederhergestellt wird. Wenn ein asynchroner
                // Vorgang vor dem Anhalten der Anwendung abgeschlossen werden muss,
                // args.setPromise() aufrufen.
                console.log('app.oncheckpoint');
            };
    
            app.start();
            console.log('app.start');
        });
    });

    When running the app, the console output is:

    ready

    app.start

    The app.onactivated event seems to be never fired. Why? app.start should queue all calls and dispatch them after app.start is called, right?

    To make it work, I need to change the code to this - however this is not very AMD like:

    (function () {
    
        WinJS.Binding.optimizeBindingReferences = true;
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: Diese Anwendung wurde neu eingeführt. Die Anwendung
                    // hier initialisieren.
                } else {
                    // TODO: Diese Anwendung war angehalten und wurde reaktiviert.
                    // Anwendungszustand hier wiederherstellen.
                }
    
                require([
                    "dojo/ready",
                    "dojo/parser",
                    "dijit/registry",
                    "dojo/dom",
                    // non referenced includes
                    "dijit/form/Button",
                    "dijit/form/DateTextBox"
                ], function (ready, parser, registry, dom) {
    
                    ready(function () {
                        
                        console.log('Ready');
                        
                        registry.byId('myButton').on('click', function () {
                            dom.byId('greetingOutput').innerHTML = 'Hello ' + registry.byId('myInput').get('value') + ' !';
                        });
                        
                    });
                });
    
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: Diese Anwendung wird gleich angehalten. Jeden Zustand,
            // der über Anhaltevorgänge hinweg beibehalten muss, hier speichern. Dazu kann das
            // WinJS.Application.sessionState-Objekt verwendet werden, das automatisch
            // über ein Anhalten hinweg gespeichert und wiederhergestellt wird. Wenn ein asynchroner
            // Vorgang vor dem Anhalten der Anwendung abgeschlossen werden muss,
            // args.setPromise() aufrufen.
        };
    
        app.start();
    })();
    
    Why?

    Monday, December 10, 2012 11:32 AM

Answers

  • Hi Paul,

    As got.dibbs pointed out, when you use the dojo init function to boot the application start-up code, it depends on when the dojo init function is executed so that the app.onactivated event is wrapped and app.start is called. And in this case, it is probably the dojo's startup execution is called too later for the WinJS start-up code to be called.

    Actually, when you creating the Windows Store javascript app project in Visual Studio, the pre-generated start-up code (in default.js file) is the recommended coding style and we should keep them as the default style in most cases. And in case you want to use other script library such as JQuery or Dojo together with WinJS, it is certainly ok, but we'd better not change the pre-generated application start-up code (especially move its location which will impact its execution point). You can just add another .js script file and put your dojo related init code in it and reference it in the default.html page.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, December 11, 2012 2:17 AM
    Moderator

All replies

  • My presumption is that the DOM Ready event is firing after the activated event, which makes sense, but doesn't appear to be documented well. I'd check myself but am not at a PC at the moment. You could check this yourself though by manually adding listeners for Dom ready and app activated and seeing which gets hit first.

    I would also think you might want to take a step back and ask why exactly you're using AMD here. Considering it appears all your required files appear to be local resources, your app will most likely be more performant if you just include them using script tagshttp://msdn.microsoft.com/en-us/library/windows/apps/hh849088.aspx#app_loading ... See this:

    Monday, December 10, 2012 3:59 PM
  • Yes, this could be the reason. So all the events are NOT queued, i.e. all events prior DOM ready are lost (since I call app.start after all modules have loaded and the DOM is ready).

    The only event I get and which is in the queue is the loaded event.

    Of course I can use script tags instead but I did not want to do that on purpose: I wanted to explore whether I can write an app in true AMD style since it is often mentioned by Microsoft that it is no problem to use WinJS together with AMD loaders, Dojo Toolkit etc.

    But it is a problem: Of course AMD loaders might delay the app startup. Nevertheless I should get an onactivated event, shouldn't I?

    Monday, December 10, 2012 6:02 PM
  • Hi Paul,

    As got.dibbs pointed out, when you use the dojo init function to boot the application start-up code, it depends on when the dojo init function is executed so that the app.onactivated event is wrapped and app.start is called. And in this case, it is probably the dojo's startup execution is called too later for the WinJS start-up code to be called.

    Actually, when you creating the Windows Store javascript app project in Visual Studio, the pre-generated start-up code (in default.js file) is the recommended coding style and we should keep them as the default style in most cases. And in case you want to use other script library such as JQuery or Dojo together with WinJS, it is certainly ok, but we'd better not change the pre-generated application start-up code (especially move its location which will impact its execution point). You can just add another .js script file and put your dojo related init code in it and reference it in the default.html page.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, December 11, 2012 2:17 AM
    Moderator
  • Why not do a separate run and load your viewmodel and the app in separate files? The app events, you can subscribe to using pub/sub.

    In your default.html head:

    <script src="/Scripts/require-jquery.js" data-main="main"></script>
    <script src="/Scripts/default.js"></script>

    In your default.js (WinJS):

    (function () {
        var app = WinJS.Application;
        app.onactivated = function (e) {
            $.publish("app/activated", e);
        };
        app.onunload = function (e) {
            $.publish("app/unloading", e);
        }
        app.onerror = function (e) {
            $.publish("app/error", e);
        }

        app.start();

    }());

    Wednesday, December 12, 2012 7:00 PM