Windows Store App Development Series: Part 16 – Data Binding Using AngularJS

Hello,

As we have covered some of the basic features of data binding using WinJS library, in this article we will explore data binding feature using Google’s AngularJS framework. One of the limitation of developing Windows Store App using WinJS library is WinJS doesn’t support two-way data binding, however you can use open source libraries or frameworks like AngularJS / KnockoutJS which supports this feature very nicely.

Please note, purpose of this article is NOT to explain how useful AngularJS framework is and all the nice features it provides to build Single Page Application. I strongly recommend you to visit angularjs.org to know more about the framework, sample code etc.

Okay, so the game plan in this article is to create simplest windows store application [Blank App template] and populate dummy data using AngularJS framework. I will also explain few changes that need to be done in AngularJS JavaScript file to make it work with Windows Store App.

Below is the app screenshot
Final App Screenshot

The top most section allows user to add employee details [name, company] to the list. As user types employee details, second panel gets populated and shows employee and company name information. It also allows user to search for an employee using ‘Search’ panel. As user types in the search box, the employee list gets filtered. Though this app looks trivial, I will explain how AngularJS makes is extremely easy to build such data-centric app.

Let’s build the app now

  1. Create a JavaScript Windows Store App using Blank App template.

    Blank App Template

    To know more about different templates, refer to Windows Store App Development Series: Part 2 – Visual Studio 2012 Templates in this series.

  2. Download AngularJS JavaScript library from angularjs.org

    Download AngularJS

  3. Add a reference to AngularJS library in default.html and hit F5 to run the application. Visual Studio will throw an exception stating ‘JavaScript runtime error: Unable to add dynamic content’. What the hell is that!

    AngularJS Error

    Well, AngularJS framework allows application developer to add dynamic markup [HTML] to a Windows Store App. For security reason, Microsoft always performs script filtering and validation on untrusted data sources [AngularJS APIs in this case]. However we can bypass this check if we know the dynamic markup is safe for the application. To know more on this, please read ‘Bypassing automatic script filtering’ section at http://msdn.microsoft.com/en-us/library/windows/apps/hh849625.aspx

    To fix JavaScript runtime error, we just need to wrap appendChild function call using MSApp.execUnsafeLocalFunction as shown below

    append: function (element, node) {
          MSApp.execUnsafeLocalFunction(function(){
              forEach(new JQLite(node), function (child) {
                  if (element.nodeType === 1 || element.nodeType === 11) {
                      element.appendChild(child);
                  }
              });
        });
      },
    

    With that change, you should be able to build and run the application. We’re back in business.

  4. Open default.js file and delete all the boilerplate code and insert following code.

    function EmployeeController($scope) {
        $scope.Employees = [
            { name: 'Scott Allen', company: 'OdeToCode' },
            { name: 'Dan Wahlin', company: 'The Wahlin Group' },
            { name: 'Scott Hanselman', company: 'Microsoft' },
            { name: 'John Papa', company: 'Pluralsight' },
        ];
    
        $scope.addEmployee = function () {
            $scope.Employees.push({
                name: $scope.newEmployee.name,
                company: $scope.newEmployee.company
            });
        }
    }
    

    Wait! What is this? Where is WinJS Application object? Well, since we are using AngularJS framework to render the UI and we are not using any of the WinJS control, we actually don’t need WinJS Application instance. Nice. Okay, back to controller code.

    AngularJS follows MV* framework, that means you’re familiar with MVC or MVVM or MVP you should be able to understand above JavaScript code.

    EmployeeController function defines Employees array and adds it to $scope variable. $scope is a special variable in AngularJS framework which acts as a glue between controller and view. All the variables and functions added to $scope are accessible in View [HTML page].

    It also contains an addEmployee function which adds new employee details to Employees array. Again note that, even though we are getting value from View, we are not using any HTTP Request object to extract the value [like in ASP.Net Web Forms], rather we are using $scope variable to get these values from View and insert the data into the list.

  5. Open default.html file, remove all the existing code and add following code
    <!DOCTYPE html>
    <html data-ng-app="">
     
    <head>
        <title>Data Binding Using AngularJS</title>
        <!-- Add WinJS, AngularJS,CSS references here -->
    </head>
     
    <body>
        <div id="ContainerDiv" data-ng-controller="EmployeeController">
            <div id="InsertNewEmployeeDiv" class="divContainer">
                <label for="newEmployeeName">Name</label>
                <input id="newEmployeeName" 
                       type="text" 
                       ng-model="newEmployee.name" />
                <label for="newEmployeeCompany">Company</label>
                <input id="newEmployeeCompany" 
                       type="text" 
                       ng-model="newEmployee.company" />
                <button id="SaveButton" 
                        ng-click="addEmployee()" 
                        class="userInput">Save</button>
            </div>
            <br />
     
            <div class="divContainer">
                You are adding - {{newEmployee.name}} - {{newEmployee.company}}
            </div>
            <br />
     
            <div id="SearchEmployeeDiv" class="divContainer">
                <label for="SearchEmployee">Search</label>
                <input id="SearchEmployee" 
                       type="text" 
                       data-ng-model="input" 
                       class="userInput" />
            </div>
             <br />
     
            <div id="EmployeeListDiv" class="divContainer">
                <ol>
                    <li data-ng-repeat="person in Employees | filter:input">
                       {{ person.name }} - {{person.company}} 
                    </li>
                </ol>
            </div>
        </div>
    </body>
    </html>
    

    Let’s understand the code step by step.

    • Root HTML tag contains data-ng-app attribute. It indicates that the HTML page contains AngularJS specific data binding expression and directives. These expressions are enclosed using {{ }} syntax.
    • ContainerDiv element in body tag contains a controller binding expression data-ng-controller = EmployeeController. This indicates that all the functions defined in EmployeeController class are available in current scope.
    • InsertNewEmployeeDiv defines ‘Employee’ model with two properties – newEmployee.name and newEmployee.company. These model properties are bind to appropriate input elements using data-ng-model syntax.
    • As user enters employee name and company information, we render the data real-time below input text boxes. Really nice two-way data binding feature.
    • data-ng-click expression binds ‘Save’ button click event to addEmployee function defined in EmployeeController. Whenever user clicks on Save button, $scope variable passes value from View to EmployeeController, which then can be accessed in addEmployee function.
    • SearchEmployeeDiv defines a new model with property ‘input’. This model is used to filter out data in the employee list box rendered below.
    • data-ng-repeat is another important AngularJS directive which renders HTML element for each item in the collection. In this case, it renders list element for each person in the collection.

      Note that we are applying Angular filter directive and associated it with the ‘input’ model property defined earlier, so that whenever user enters information in SearchEmployeeDiv, we filter the employee list accordingly.

  6. That’s it. Run the application and you should be able to add new employee and filter the data as shown below.

    Add New Employee
    Add New Employee

    Search Employee
    Search Employees

    Please note, I have modified the CSS to add some colors to the app. Please download the application and make the changes as per your need.

Summary

In this article we have covered integration of AngularJS framework in a Windows Store App. We also discussed two-way data binding, directives, expressions and their usage in a Windows Store App.

I hope it was useful to you.

Thanks for reading.

8 Comments

  1. sudhirchekuri · September 30, 2013 Reply

    Superb tutorial. Clean and simple. No chrome here only content.

  2. hanan · January 31, 2014 Reply

    Excuse me, i wanted to know where can i put code mentioned in point 3 not 4 :
    append: function (element, node) {
    MSApp.execUnsafeLocalFunction(function(){
    forEach(new JQLite(node), function (child) {
    if (element.nodeType === 1 || element.nodeType === 11) {
    element.appendChild(child);
    }
    });
    });
    },

    • Prasad Honrao · January 31, 2014 Reply

      Search for ‘append’ function in referenced Angular.JS file and replace it with the code as mentioned in the article. It should solve the problem. Source code for all the articles is available on GitHub. Let me know if you need any additional help. Thanks.

  3. Dan · March 21, 2014 Reply

    Thank you for the article.
    The link to the git repo in the article is broken. I assume you moved the code to the other repo that you reference in your previous comment.

  4. Ankit · October 19, 2014 Reply

    Now there is a much better, cleaner and safer way to get around this issue. Angular.js now provides the ng-csp directive which you can include in your html tag and everything works beautifully. Check out Timmy’s blog post to see it in action.

    http://www.timmykokke.com/2014/07/angular-in-a-windows-store-app/

Leave a Reply