RequireJS is great for that, but I had considerable trouble getting it to work with WinJS. When I did get it working I then had trouble getting it to work properly.
RequireJS is expected to be initialised with an include reference in the page html with a data-main tag, but this doesn't really work with the WinJS app lifecycle, so it took a bit of work to get it behaving the way I expected.
Eventually I got it working, and working with async initialisation code which was a key part of the initialisation process in my sample app.
So the basics of getting RequireJS working in WinJS is the following - I have probably made a million big JavaScript no-no's here, but as I said, still learning.
default.html - add
<script src="/js/require.js" ></script>before default.js
default.js - initialise requireJS and include whatever dependencies you want to use in your startup code.
app.addEventListener("activated", function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.closedByUser) {
                // TODO: This application has been launched after a requested shutdown. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
 
            if (app.sessionState.history) {
                nav.history = app.sessionState.history;
            }
 
            //RequireJS Initialisation here
            require.config({
                baseUrl: '/js'
            });
 
            //this creates a promise that calls complete() when the initAsync promises finish
            //all this code happens within the require context so we are guaranteed that the dependencies are resolved before the promise is resolved
            //the initAsync methods return promises that load data from internal json data files
            //persistence.loadState is synchronous code so doesn't return a promise
            var loadPromise = new WinJS.Promise(function (complete) {
                require([
                    'persistence',
                    'game/staticdata/itemClassStore',
                    'game/staticdata/itemStore',
                    'game/gamestate/world',
                    'game/gamestate/characters',
                    'game/classes/character'
                ], function (persistence, itemClassStore, itemStore, world, characters, character) {
 
                    itemClassStore.initAsync()
                        .then(function () { return itemStore.initAsync(); })
                        .then(
                            function () {
                                var data = persistence.loadState();
                                world.fromJson(data);
                                complete();
                            }
                        );
 
 
                });
            });
 
            //args.setPromise is a function on the activate event which allows you to wait for promises to complete before continuing
            args.setPromise(
                loadPromise
                    .then(function () { return WinJS.UI.processAll(); })
                    .then(
                        function () {
                            if (nav.location) {
                                nav.history.current.initialPlaceholder = true;
                                return nav.navigate(nav.location, nav.state);
                            } else {
                                return nav.navigate(Application.navigator.home);
                            }
                        }
                    )
            );
        }
    });
xPage.js - resolve your dependencies in the page ready function with a call to require(), and perform your page initialisation as per normal.
////// /// /// /// (function () { "use strict"; WinJS.Namespace.define("CharacterSelect", { CharacterSelectViewModel: WinJS.Class.define( //the viewmodel constructor takes the injected requireJS dependency from the page ready code. function (world) { this._charactersModule = world.characters; this._itemsDataSource = new WinJS.Binding.List(this._charactersModule.characters); this._inventoryDataSource = new WinJS.Binding.List(null); }, { _charactersModule: null, _itemsDataSource: null, _inventoryDataSource: null, _selectedCharacterId: 0, selectedCharacterId: { get: function () { return this._selectedCharacterId; }, set: function (value) { this._selectedCharacterId = value; if (value == 0) { this._inventoryDataSource = new WinJS.Binding.List(null); } else { this._inventoryDataSource = new WinJS.Binding.List(this._charactersModule.get(value).inventory.items); } this._getObservable().notify("selectedCharacterId", value); this._getObservable().notify("inventoryDataSource", this._inventoryDataSource); } }, listDataSource: { get: function () { return this._itemsDataSource; } }, inventoryDataSource: { get: function () { return this._inventoryDataSource; } }, addNew: function () { WinJS.Navigation.navigate("/pages/newCharacter/newCharacter.html"); }, deleteCharacter: function (that) { that._charactersModule.deleteCharacter(this.selectedCharacterId); that._itemsDataSource = new WinJS.Binding.List(this._charactersModule.characters); that._getObservable().notify("listDataSource", that._itemsDataSource); } }, {}), }); WinJS.UI.Pages.define("/pages/characterSelect/characterSelect.html", { // This function is called whenever a user navigates to this page. It // populates the page elements with the app's data. ready: function (element, options) { require( [ 'persistence', "appbar", "game/gamestate/world" ], function (persistence, appbar, world) { //normal page initialisation code - all dependency modules are initialised at this point //create view model (passing in resolved dependencies) and bind to relevant events //(WinJS only has 1-way bindings and can't declaratively bind to button events that i can see) var section = element.querySelector("section"); var viewModel = new CharacterSelect.CharacterSelectViewModel(world); var observableviewModel = WinJS.Binding.as(viewModel); WinJS.Binding.processAll(section, observableviewModel); document.getElementById("cmdCreate").addEventListener("click", observableviewModel.addNew, false); document.getElementById("cmdDeleteCharacter").addEventListener( "click", function(){ observableviewModel.deleteCharacter(observableviewModel); persistence.saveState(); } , false ); document.getElementById("characters").winControl.onselectionchanged = function (ev) { var selection = document.getElementById("characters").winControl.selection; if (selection.getItems()._value.length > 0) { viewModel.selectedCharacterId = selection.getItems()._value[0].data.id; appbar.characterSelectSelected(); } else { viewModel.selectedCharacterId = 0; appbar.characterSelectDeSelected(); } }; appbar.characterSelectInit(); } ); }, unload: function () { // TODO: Respond to navigations away from this page. }, updateLayout: function (element, viewState, lastViewState) { /// // TODO: Respond to changes in viewState. } }); })(); 
No comments:
Post a Comment