Monday, November 18, 2013

MVVM – Windows Phone 8 App using HTML5/JavaScript Primer

MVVM – Windows Phone 8 App using HTML5/JavaScript Primer
 
Purpose: The purpose of this document is to illustrate how to how to apply MVVM (Model-View-ViewModel) architectural pattern when developing Windows Phone 8 Product catalog App using HTML5/JavaScript
 
Challenge: You may need to develop a modern application integrated with Microsoft Dynamics AX 2012 for the purposes of demonstration, POC or to be deployed in production environment. The question is what technology and architectural pattern to use in order to facilitate application development and maintenance efforts        
 
Solution: In this scenario we'll develop Windows Phone 8 App using HMTL5/JavaScript based on Windows Phone HTML5 App template
 
Walkthrough
 
First off let's create a new project using Visual C# > Windows Phone > Windows Phone HTML5 App template
 
New Project
 
 
Please note that essentially it is C#.NET App which wraps up HTML5 code with Web browser control. As opposed to Windows Store Apps written in HTML5/JavaScript where JavaScript (WinJS) is hosted in Windows runtime/OS, Windows Phone 8 Apps written in HTML5/JavaScript are not natively integrated with OS 
 
Solution Explorer
 
 
Then we'll apply MVVM (Model-View-ViewModel) architectural pattern for development of Product catalog app
 
Solution Explorer
 
 
In order to execute JavaScript in Web browser control in Windows Phone 8 App I'll need to enable scripting (IsScriptEnabled="true") as showed below
 
MainPage.xaml
 
<phone:PhoneApplicationPage
    x:Class="HTML5App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
 
    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <phone:WebBrowser x:Name="Browser"
                          HorizontalAlignment="Stretch"
                          VerticalAlignment="Stretch"
                          Loaded="Browser_Loaded"
                          NavigationFailed="Browser_NavigationFailed"
                          IsScriptEnabled="true" />
    </Grid>
 
    <!-- ApplicationBar -->
    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" Mode="Minimized">
            <shell:ApplicationBarIconButton IconUri="/Assets/AppBar/appbar.back.rest.png" IsEnabled="True" Text="back" Click="BackApplicationBar_Click"/>
            <shell:ApplicationBarIconButton IconUri="/Assets/AppBar/appbar.next.rest.png" IsEnabled="True" Text="forward" Click="ForwardApplicationBar_Click"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="home" Click="HomeMenuItem_Click" />
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>
 
</phone:PhoneApplicationPage>
 
As soon as I'm not going to use ApplicationBar I can delete this entire section
Please note that index.html will look like this by default and I'm going to change it later
 
index.html
 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link rel="stylesheet" type="text/css" href="/html/css/phone.css" />
        <title>Windows Phone</title>
    </head>
    <body>
        <div>
            <p>MY APPLICATION</p>
        </div>
        <div id="page-title">
            <p>page title</p>
        </div>
    </body>
</html>
 
Now let's review how I implemented Model, View and ViewModel
The model encapsulates business logic and data. Please see below how I define Product object (function) which has 2 attributes: ID and Name as a part of the model
 
The view model encapsulates presentation logic and state. Please see below how I define ObservableArray of products with respective function(s) (GetProducts) as a part of the view model
 
Model and ViewModel:  JS (JavaScript.js)
function Product(id, name) {
    var self = this;
    self.id = ko.observable(id);
    self.name = ko.observable(name);
}
 
function ProductViewModel() {
    var self = this;
    self.products = ko.observableArray();
    self.GetProducts = function () {
        self.products.push(new Product("X", "AlexProductX"));
    }
}
 
Please note that Model and ViewModel definition is done in JavaScript (JS)
MVVM (Model-View-ViewModel) pattern implementation is different in JavaScript (JS) comparing to classic object-oriented languages such as C#.NET. Please note that JavaScript (JS) has objects which can contain data and methods that act upon that data. Objects can contain other objects. JavaScript (JS) does not have classes, but it does have constructors which do what classes do, including acting as containers for class variables and methods. JavaScript (JS) does not have class-oriented inheritance, but it does have prototype-oriented inheritance
 
Now let's review a view
 
Important to mention is that in order to link view and view model by means of binding I used the capabilities of knockout.js JavaScript (JS) library
 
Knockout (ko) is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model. Any time you have sections of UI that update dynamically (e.g., changing depending on the user's actions or when an external data source changes), Knockout (ko) can help you implement it more simply and maintainably
 
Please find more info about Knockout (ko) JavaScript (JS) library here: http://knockoutjs.com
 
The view encapsulates the UI and any UI logic, and this is when I changed index.html populated by default from the template. Please see below how I iterate through the list of products and map view model object properties with elements of UI for display
 
View: HTML (index.html)
 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Product Catalog</title>       
    <script src="js/jquery-1.10.2.min.js"></script>
   <script src="js/knockout-2.3.0.js"></script>
    <script src="js/JavaScript.js"></script>
    <script>
        $(document).ready(function () {
            var productViewModel = new ProductViewModel();
            productViewModel.GetProducts();
            ko.applyBindings(productViewModel);
        })
    </script>  
    <link href="css/StyleSheet.css" rel="stylesheet" />
</head>
<body>
<h1>Product Catalog</h1>
<table>   
    <tbody data-bind="foreach: products">
        <tr>
            <td id="id" data-bind="text: id"></td>
            <td id="name" data-bind="text: name"></td>
        </tr>   
    </tbody>
</table>
</body>
</html>
 
Please note that I also used JQuery JavaScript (JS) library because it is needed to be able to use $document variable. jQuery is a multi-browser (cf. cross-browser) JavaScript library designed to simplify the client-side scripting of HTML. Please find more info about JQuery JavaScript (JS) library here: http://jquery.com
 
Please note that I created a CSS file to define a style
 
Style: CSS (StyleSheet.css)
 
table {
   margin-top: 50px;
   margin-left: 50px;
}
td {
   border-width:1px;
   border-style: solid;
   height: 100px;
   text-align: center;
}
#id {
   width: 100px;
   color: white;
   background-color: black;
}
#name {
   width: 400px;
   color: black;
   background-color: white;
}
 
Please note that I defined different styles to display product ID and Name
As the result our Product catalog application will look like below
 
Result
 
 
Please review the following article to learn how to quickly connect your application to Microsoft Dynamics AX 2012 to test out the integration: http://ax2012aifintegration.blogspot.com/2013/04/microsoft-dynamics-ax-2012-windows-8.html
 
In case you are developing a mobile application for production please review the best practice guidance on Developing Mobile apps for Microsoft Dynamics AX 2012 here: http://www.microsoft.com/en-us/download/details.aspx?id=38413
 
Summary: This document describes how to apply MVVM (Model-View-ViewModel) architectural pattern when developing Product catalog sample Windows Phone 8 App using HTML5/JavaScript.
 
Author: Alex Anikiev, PhD, MCP
 
Tags: MVVM, Model-View-ViewModel, Windows Phone 8 App, HTML5, JavaScript, JS, Microsoft Dynamics AX 2012.
 
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the concepts and describe the examples.
 

4 comments:

  1. Similar methods exist for most other transformations. Also, avoid animating with JavaScript libraries! convert psd to wordpress

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Srry but how can i get working js files with my wp8.0 project?

    ReplyDelete