Building Windows 8 Applications with AngularJS aka Oh Yes I Did!

I am a huge fan of HTML5 and JavaScript because they run on just about anything. I remember when web applications were in their infancy and the golden promise was that you could make a web application feel just like a desktop application – in a browser! Now we have come full circle into this weird parallel universe where we are putting web applications INTO desktop applications. It is heady and high times my friend!

Backstory

Aside from my JavaScript interests, I spend a lot of time doing events for the community. My partner in crime Aaron Murray @WeAreFractal and I are putting on an event called The JavaScript Taste Test with Microsoft where we exploring what you can actually do with HTML5 and JavaScript.

I was personally intrigued if I could write a Windows 8 application in JUST HTML5 and JavaScript. Could I do it on a Mac? Would it be hard? Would THIS happen to me?

Lost Ark

Well I am going to just spare you the agony of wondering if I am even alive right now. It was pretty painless and felt pretty much like writing a web application. I kept my eyes closed the entire time! +1 if you get the joke.

Part Zero: The Source Files

You can download my project here if you want to follow along.

Part One: Testing the Waters

Microsoft has done a good job lately of making helpful tools available for the development community free of charge.

If you do not have a copy of Windows, you can download a VM image from http://www.modern.ie/en-us to get started.

The most economical choice is to use the VirtualBox image since VirtualBox is free of charge. I have a lot of friends that swear by VirtualBox and I take their word for it. I use Parallels and so I downloaded the VMWare Fusion image and just converted it. Took me all of about 40 minutes to download and get up and running. Bam!

From the VM, I downloaded Visual Studio Express for Windows 8 from http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-windows-8.

So, at this point, I was still pretty skeptical, so I figured the obligatory “Hello World” was in order, which I found here.

This took all of about 20 minutes to do and, so now I have about a 2 hour investment into the process. Not too bad!

Part Two: So About That AngularJS?

So now my curiosity is totally piqued. Can it be done man!?

Step 1: Create a New Project

So first things first, we need to create a new project. Ctrl + shift + n and you are on your way!

I left all the defaults as is and called the project HelloAngular. You can see my settings in the image below.

HelloAngular Step One

Step 2: Import AngularJS

Windows 8 applications require that all your scripts run local for security reasons and so I downloaded the latest angular.min.js and dropped it into the js folder of the project.

Step 3: Include AngularJS and Roll Dice

So I wanted to see if I could just bootstrap an AngularJS application and so I referenced the script and added ng-app to the html tag of the default.html file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html ng-app>
<head>
    <meta charset="utf-8" />
    <title>Hello AngularJS!</title>

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

    <!-- HelloAngular references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/angular.min.js"></script>
    <script src="/js/default.js"></script>
</head>

Oh noes!

Oh Noes!

“JavaScript runtime error: Unable to add dynamic content.”

Step 4: A Little Help From My Friends

To the Googles! A little poking around and I found that I was not the first one to experience this. A gentleman by the name of Jonathan Channon shed all the light I needed on this conundrum. You can read his post here.

Enter JavaScript juggernaut Elijah Manor @elijahmanor and his breakdancing crew with a custom version of jQuery. WINDOWS 8 STYLE!

Oh appendTo… I love you!

The moral of the story is to use jquery-win8 from here

Add the file to the js folder.

Hello Angular Step Two

Include the script and make one small tweak as you can see below. Friction removed!

1
2
3
4
5
6
7
    <link href="/css/default.css" rel="stylesheet" />
    <script src="js/jquery-1.8.2-win8-1.0.min.js"></script>
    <script type="text/javascript">
        jQuery.isUnsafe = true;
    </script>    
    <script src="/js/angular.min.js"></script>
    <script src="/js/default.js"></script>

Behold the choir of angels! It works!

Step 5: Build Something!

I am not going to delve too much into the AngularJS application I built since it is super 101 level stuff, but here is the basic rundown.

In the js folder, open default.js and jump right to the bottom of the file. Just above the app.start(); function call is where I decided to craft my AngularJS app.

First, I define my AngularJS module, and then I define a MainCtrl on that module to hold my data and methods for the application.

1
2
3
4
5
6
    // AngularJS Stuff
    var myApp = angular.module('app', []);

    myApp.controller('MainCtrl', function ($scope) {
        $scope.greeting = 'Hello AngularJS!';
    });

Now that I have a defined module, I am going to bootstrap the AngularJS application to use that module. That is as simple as updating ng-app to ng-app=”app” in the html tag.

1
<html ng-app="app">

Now I want to give the reins to MainCtrl to do its thing. I do this by using the AngularJS ng-controller directive with a value of MainCtrl. This essentially sets up the relationship between $scope and the HTML. Notice that I created a greeting property on $scope when I defined the controller. I can bind to that in the HTML using the doubly curly brace syntax a la {{greeting}}.

Side note: Directives are an entirely different conversation for another day, but for now think of them as “html elements with super powers”.

1
2
3
<body ng-controller="MainCtrl">
    <h1>{{greeting}}</h1>
</body>

Moving along…I am going to add a messages array to hold well…messages. Self documenting code FTW! And I am going to create a method called addMessage that adds a message to the front of the array via unshift. By adding these methods and properties to the $scope object, I am making them available to the elements that exist within the HTML element that we defined the controller on. You will notice that I am also setting a message property to an empty string. More on that in just a moment.

1
2
3
4
5
6
7
8
9
10
    var myApp = angular.module('app', []);

    myApp.controller('MainCtrl', function ($scope) {
        $scope.greeting = 'Hello AngularJS!';
        $scope.messages = [];
        $scope.addMessage = function (m) {
            $scope.messages.unshift(m);
            $scope.message = '';
        }
    });

To the HTML! Let’s start with the messages. I want to display all the messages that exist and so I do that with ng-repeat. ng-repeat is an AngularJS directive that essentially loops over an array and stamps out whatever element it is defined on. So in this case we are saying “Create a new p tag with the value of m for every message that exists in messages“. From there we are back to the curly braces for the binding.

And to add a message, we first declare ng-model=”message” on the messageInput element. This essentially sets up two-way binding with $scope from the HTML side. We are going to call addMessage by adding ng-click=”addMessage(message)” to the messageButton. The ng-click directive takes all of that messy event listening handlers and takes care of the biz for you. We are passing it the message value which is essentially whatever is in the messageInput field thanks to ng-model.

1
2
3
4
5
6
7
8
9
<body ng-controller="MainCtrl">
    <h1>{{greeting}}</h1>
    <p>Leave a message.</p>
    <input id="messageInput" ng-model="message" type="text" />
    <button id="messageButton" ng-click="addMessage(message)">Say "Hello"</button>
    <div id="greetingOutput">
        <p ng-repeat="m in messages">{{m}}</p>
    </div>
</body>

And that my friends is how I did it! Behold!

Angular Metro

Conclusion

I could have definitely dug into the AngularJS side a bit more, but I wanted to highlight how easy it was to get up and running, even for a guy on a Mac running Windows in a VM. It was really just HTML5 and JavaScript! Hooray!

AngularJS
http://angularjs.org/

Modern.ie
http://www.modern.ie/en-us/

VirtualBox
https://www.virtualbox.org/

jQuery for Windows 8 Store Applications
https://github.com/appendto/jquery-win8

Create your first Windows Store app using JavaScript
http://msdn.microsoft.com/en-us/library/windows/apps/br211385.aspx

Building Windows 8 Applications with AngularJS aka Oh Yes I Did!

12 Responses

  1. That’s pretty sweet. I did it earlier and within about 45 minutes I had a working app (including download/install time).

    John C. Bland II March 19, 2013 at 3:12 pm #
  2. Oh and an interesting note, you can get Angular and jQuery from NuGet:
    http://nuget.org/packages/angularjs/1.0.5
    http://nuget.org/packages/jQuery/

    I did not use these in my tests but checked for them while re-familiarizing myself w/ VS.

    John C. Bland II March 19, 2013 at 3:15 pm #
  3. hej,
    ok but this is super simple scenario. what about nested views with win-controls? have you tried to port it to angular?
    I fear that WinJs and PageControl make some magic behind scene and it wont be that easy to just call angular.module().configure

    pawel April 11, 2013 at 4:19 pm #
  4. Worth noting that the Win8 specific version of jQuery is not needed. Win 8 is fully compatible with jQuery 2.0.

    Jesse Gavin June 4, 2013 at 6:38 pm #
  5. Yep! That happened post blog post :D Sneaky guys! I should update the post though…

    simpulton June 4, 2013 at 6:47 pm #
  6. Check out: https://github.com/codemonkeychris/angular-winjs, it’s a library to enable using WinJS UI controls like ListView natively within Angular.

    Josh November 3, 2013 at 1:18 am #
  7. Thanks Josh!

    simpulton November 3, 2013 at 2:01 am #
  8. The jquery-win repo no longer contains the js file, but you can get it here:
    https://github.com/th2tran/public/tree/master/Win8.AngularJS.App1/AngularJS.App1/_assets/js

    Dan March 21, 2014 at 1:06 am #
  9. Trying to run Angular 1.2.15 with jQuery 2.1.0 was puzzling….

    Angular has an unsafe line where it adds an element to the DOM that apparently jQuery executes in a way that is not safe (I am not sure what I would expect from jQuery, as the Angular-element has a lot of properties that Windows could mark as “unsafe”; it should probably throw an error).

    Anyway, putting this last line in an MSApp.execUnsafeLocalFunction works; the result:
    MSApp.execUnsafeLocalFunction(function () {
    !angular.$$csp() && angular.element(document).find(‘head’).prepend(‘@charset “UTF-8″;[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}’);
    });

    Raoel Oomen March 25, 2014 at 2:27 pm #
Trackbacks/Pingbacks
  1. AngularJS?????-? | web????—???? - November 4, 2013

    […] Lukas Ruebbelke???????AngularJS??????????2012?4?????????AngularJS????????????AngularJS????????????AngularJS??Windows 8 APP? […]

  2. WinJS | DiscVentionsTech - April 13, 2014

    […] BEST: http://onehungrymind.com/windows-8-and-angularjs/ […]

  3. Blend for visual studio | DiscVentionsTech - April 13, 2014

    […] BEST: http://onehungrymind.com/windows-8-and-angularjs/ […]

Leave a Reply