Search code examples
navigationtypescriptwinjsvisual-studio-cordovamulti-device-hybrid-apps

Cordova Typescript app + WinJS.UI.Pages.render fails on Win8, WP8 but works on Android


I'm creating a single page navigation app using Microsoft's Multi-device Hybrid App template for Typescript and WinJS. The app builds for Win8, WP8, and Android and deploys to emulators just fine. However, the Win8 and WP8 apps do not navigate properly to the first page of the app. Android navigates just fine using the same code.

WinJS has navigation state saving functionality, but doesn't actually do the navigation itself. I borrowed the actual navigation code from a Typescript/WinJS sample, Encyclopedia, found here.

The relevant portion that seems to fail is shown below:

 args.detail.setPromise(
            WinJS.Promise.timeout().then(function () {
                if (oldElement.winControl && oldElement.winControl.unload) {
                    oldElement.winControl.unload();
                }
                return WinJS.UI.Pages.render(args.detail.location, newElement, args.detail.state, parented);
            }).then((control) => {
                    this.element.appendChild(newElement);
                    this.element.removeChild(oldElement);
                    oldElement.innerText = "";
                    this.navigated();
                    parentedComplete();
                })
            );

After the render command returns, on Android, the element's innerHTML contains the page pointed to in the path (args.detail.location). On Win8 and WP8, the element is still blank.

This part of the code is triggered by WinJS specific html in the root index.html file.

<div id="contenthost" data-win-control="TurnstileTS.PageControlNavigator" data-win-options="{home: './views/home/HomeView.html'}"></div>

This path works just fine in Android. The absolute path in the Ripple, web-based Android emulator is http://localhost:4400/views/home/HomeView.html.

This path does not work in WP8 or Win8, but it doesn't throw an exception, either. The screen is just blank. The absolute path during a debug run of the Win8 app is ms-appx://io.cordova.turnstile/www/views/home/HomeView.html.

I don't see what could be wrong. I'm using the latest version of WinJS and the typings included in the WinJS build.

edit Another piece of the puzzle: this sample uses Cordova and WinJS, but not Typescript. Everything is in javascript. It has its own navigator function as well. This DOES seem to work on Win8 and WP8. As far as I can tell, it is calling the same function in the WinJS library. I really can't find any major differences between this sample and what I'm trying to do.

edit #2 OK, after discovering that the javascript console has started spitting out errors, I get these messages when running it in Win8:

APPHOST9623: The app couldn’t resolve ms-appx://57059lmcpherson.turnstile/views/home/HomeView.css because of this error: RESOURCE_NOT_FOUND.

Actually, there are a bunch of these messages. So, there's something wrong.

I read something about using a starting slash for the path is unacceptable for Windows/Cordova apps, so I've tried to rewrite them. If a javascript file is in the same subdirectory as the html file, the path reference should just be the file name with no slashes. However, the javascript console shows that this has been interpreted in Win8 to mean the root of the www folder (generated during the build). If I try to hard code it to the actual path using "/views/home/HomeView.css", it still can't find the file. I'm not exactly sure why the body of the HTML doc is not loading if the javascript console is indicating it's tried to load the scripts in the head.


Solution

  • edit - 11/14/2014 - post CTP3 release!
    

    There seems to be another problem with the MDHA template... the winstore-compat.js shim file that is used to make 3rd party libraries compatible with the Windows 8 application model (native access instead of webview like android or iOS) causes problems with the MDHA template when using the WinJS navigation model. I was opening local html fragments into a div in a root html page... the shim intercepts this fragment and modifies it in a way that causes the entire page to silently fail. If you comment out the shim, navigation works. (It is located in merges/windows/scripts/platformOverrides.js) This is NOT a permanent solution because then you may not be able to use other 3rd party libraries.

    Issue is registered at the WinJS github issue tracking page here.

    end edit
    

    One solution, although still frustrating, is to start with the known working example of single-page navigation rather than start with the blank template.

    This sample that I linked before uses all JavaScript and works with single-page navigation out of the box. I left the original index.html and index.js, but replaced all of the subpages and scripts. It still worked. Then I added in the TypedMVVM framework files and it still worked.

    I still have no idea what is wrong with how I implemented my own single-page navigation using Typescript, but I'm happy to use this alternative for now.

    edit - Also, I have found that leading "/" characters the paths for the Win8/WP8 projects don't work well. I had to use a leading dot "./" or nothing and all paths had to be relative to the current html file. (a lot of ".." to go to previous directory)

    edit2 The leading dot for paths is EXTREMELY important. Binding in Win8 and WP8 apps was not working at all and I finally tracked it down to a simple statement in the script for the page.

    This does NOT work:

    WinJS.UI.Pages.define("/views/main/MainView.html", new MainView());
    

    This DOES work:

    WinJS.UI.Pages.define("./views/main/MainView.html", new MainView());
    

    I felt like breaking something after discovering this.