2
votes

I have a web application that uses requirejs to load its modules. The web applications works without problems in any desktop browser, it also works on iOS and Android when packaged with Cordova. Does however NOT work when building a Windows Phone 8 Cordova application.

I get the following error:

"View Not Found: Searched for "views/shell" via path "text!views/shell.html"

(I'm using Durandal)

I have the following application structure:

  • lib/require/require.js
  • www/app/viewmodels/shell.js
  • www/app/views/shell.html
  • www/app/main.js
  • www/index.html (contains line: )
  • :

www/app/main.js contains the following code:

requirejs.config({
    //baseUrl: 'x-wmapp0:www/app',
    baseUrl: 'app',
    enforceDefine: true,
    paths: {
        'text': '../lib/require/text',
        'durandal':'../lib/durandal/js',
        'plugins' : '../lib/durandal/js/plugins',
        'transitions' : '../lib/durandal/js/transitions',
        'knockout': '../lib/knockout/knockout-2.3.0',
        'bootstrap': '../lib/bootstrap3/js/bootstrap',
        'jquery': '../lib/jquery/jquery-1.9.1',
        'modules' : 'modules'
    },
    shim: {
        'bootstrap': {
            deps: ['jquery'],
            exports: 'jQuery'
       }
    }
});

define(['durandal/system', 'durandal/app', 'durandal/viewLocator', 'bootstrap'],  function (system, app, viewLocator, bootstrap) {
    //>>excludeStart("build", true);
    system.debug(true);
    //>>excludeEnd("build");

    app.title = 'MyApp';

    app.configurePlugins({
        router: true,
        dialog: true,
        widget: true
    });

    app.start().then(function() {
        //Replace 'viewmodels' in the moduleId with 'views' to locate the view.
        //Look for partial views in a 'views' folder in the root.
        viewLocator.useConvention('viewmodels', 'views', 'views');

        //Show the app by setting the root view model for our application with a transition.
        app.setRoot('viewmodels/shell', 'entrance', 'applicationHost');
    });
});

This code works perfectly on all devices except WP8. I tried the line baseUrl: 'x-wmapp0:www/app' to set the actual path used internally by WP8 Cordova, but that does not work. Is that because it is not a path starting with '/' or http?

Any ideas on how to configure requirejs to be able to load modules and views using requirejs?

3

3 Answers

6
votes

See if this is any help to you http://mikaelkoskinen.net/durandal-phonegap-windows-phone-8-tutorial/

Also, as of the 18th October 2013, Phonegap Build has added beta support for WP8. Add "winphone: as the gap:platform and ensure you're using phonegap 3.0. We're currently having no luck but maybe you can use that.

0
votes

I just solve this problem for myself as well, what I ended up doing was waiting for the deviceloaded event before I loaded my main.js.

Cordova applies a patch to XMLHttpRequest which has been applied when deviceloaded has been triggered.

In my app I it ended up looking similar to this:

<script src="js/require.js"></script>
<script>
document.addEventListener('deviceloaded', function() {
  var script = document.createElement('script');
  script.src = 'js/main.js';
  document.body.appendChild(script);
}, false);
</script>

I hope that works out for you as well!

One other thing, I noticed in my app that if I try to load weinre I couldn't get my app started at all with require.js. I haven't been able to research this further yet though.

0
votes

I recommend to set a breakpoint to cordovalib/XHRHelper.cs HandleCommand method and see what is going on. Also the following version of HandleCommand could work better for you

    public bool HandleCommand(string commandStr)
    {
        if (commandStr.IndexOf("XHRLOCAL") == 0)
        {
            string url = commandStr.Replace("XHRLOCAL/", "");

            Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);

            try
            {

                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (isoFile.FileExists(uri.AbsolutePath))
                    {
                        using (
                            TextReader reader =
                                new StreamReader(isoFile.OpenFile(uri.AbsolutePath, FileMode.Open, FileAccess.Read))
                            )
                        {
                            string text = reader.ReadToEnd();
                            Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
                            return true;
                        }
                    }
                }

                url = uri.AbsolutePath;
            }
            catch { }

            var resource = Application.GetResourceStream(new Uri(url, UriKind.Relative)) ??
                // for relative paths and app resources we need to add www folder manually
                // there are many related issues on stackoverflow + some prev worked sample don't because of this
                Application.GetResourceStream(new Uri("www/" + url, UriKind.Relative));

            if (resource == null)
            {
                // 404 ? 
                Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404" });
                return true;
            }
            else
            {
                using (StreamReader streamReader = new StreamReader(resource.Stream))
                {
                    string text = streamReader.ReadToEnd();
                    Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
                    return true;
                }
            }
        }

        return false;
    }