Дизайн приложений
Вам понадобится

Для разработки под Windows вам понадобиться следующее ПО:

Бесплатная версия Windows 10

После обновления вы бесплатно получаете Windows 10 на свое устройство.

Visual Studio 2015

Бесплатная версия Visual Studio, позволяющая создавать приложения для платформы Microsoft Azure.

SDKs и доп. инструменты

Инструменты разработки приложений для платформы Microsoft Azure.

Используем AngularJS в Windows Phone 8.1 приложениях



В этой статье я расскажу вам как подключить и начать использовать популярный JavaScript фреймворк AngularJS для разработки приложений для Windows Phone 8.1.

Вы сможете подключить AngularJS к своему проекту и начать использовать его возможности.

Создаем проект и подключаем AngularJs

Создаем новый проект для Windows Phone 8.1 на JavaScript по шаблону Blank App.



Подключаем AngularJS. Он доступен в виде установочного пакета в NuGet.

Открываем NuGet Package Manager Console и выполняем команды:

install-package AngularJS.Core
install-package AngularJS.Animate
install-package Angular.UI.UI-Router

AngularJS.Core – библиотека с базовыми возможностями AngularJS.

AngularJS.Animate – анимационные возможности.

Angular.UI.UI-Router – навигация, работа с представлениями.

Angular-WinJS — чтобы получить возможность использовать AngularJS вместе с WinJS, вам нужно установить этот модуль. К сожалению, в настоящее время он не опубликован в виде пакета NuGet и нам придется скачать его с GitHub вручную.

Добавьте скачанный скрипт в папку scripts в проекте:



Вносим изменения в библиотеки


Как только вы попробуете подключить библиотеки Angular на вашу страницу и запустить приложение, произойдет страшное, то есть ошибка.



В соответствии с моделью безопасности Windows Phone приложений, вы не можете динамически менять содержимое элементов страницы. Но можете это делать внутри конструкции

MSApp.execUnsafeLocalFunction(function () {

});

То есть, в файле scripts/angular.js необходимо обернуть все изменения innerHTML или вызовы метода prepend или insert.. в эту конструкцию.

Исправленный файл доступен по ссылке на Github

Используем AngularJS на странице приложения


1. Откроем файл default.html, добавим ссылки на библиотеки AngularJS.



В теле страницы разместим специальный контейнер, в который средствами AngularJS мы будем загружать представление:

<div ui-view></div>
Полный код файла default.html

<!DOCTYPE html >
<html>
<head>
    <meta charset="utf-8" />
    <title>demo</title>

    <link href="//Microsoft.Phone.WinJS.2.1/css/ui-light.css" rel="stylesheet" />
    <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
    <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
    <!-- Angular references -->
    <script src="/scripts/angular.js"></script>
    <script src="/scripts/angular-animate.js"></script>
    <script src="/scripts/angular-ui-router.js"></script>
    <script src="/scripts/angular-winjs.js"></script>
    <!-- demo references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>

</head>
<body class="phone" >   
    <div ui-view></div>
</body>
</html>


2. Создадим новую папку views в который мы будем хранить представления для страниц.

3. В папке views создадим файл mainView.html для представления главной страницы.

Наша основная страница будет содержать только поздравление с прошедшим праздником и кнопку на панели действий.

Полный код файла mainView.html
 
<div class="demoView fragment">
    <h1 style="font-size:2em">
        {{greeting}}
    </h1>   
    <win-app-bar>
        <win-app-bar-command icon="'accept'" label="'ok'" ng-click="ok()"></win-app-bar-command>
    </win-app-bar>
</div>

Конструкция {{greeting}} поможет нам вывести значение переменной, которую мы определим в контроллере, а кнопка подтверждения будет представлять собой кнопку на панели действий, созданную средствами WinJS.

4. Откроем js/default.js – основной файл приложения, в котором будет находиться весь код и заменим его содержимое.

Полный код файла default.js

 (function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    var angular_app = angular.module('demo', ['ui.router', 'ngAnimate', 'winjs']);

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                
            } else {
                
            }

            var angularLoadedSignal = new WinJS._Signal();
            angular.element(document).ready(function () {
                try {
                    angular.bootstrap(document, ['demo']);
                    angularLoadedSignal.complete();
                } catch (e) {
                    
                    if (!(typeof e.message == 'string' || e.message instanceof String)) {
                        throw e;
                    }

                    if (e.message.indexOf('[ng:btstrpd]') !== 0) {
                        throw e;
                    }
                }
            });

            args.setPromise(angularLoadedSignal.promise);

        }
    };

    app.oncheckpoint = function (args) {
      
    };

    //наполняем представление данными и обрабатываем события
    angular_app.controller('mainViewCtrl', ['$scope', function ($scope) {

        $scope.greeting = 'С Днем народного единства!';


        $scope.ok = function () {
            var msgpopup = new Windows.UI.Popups.MessageDialog
            ("Если вы хотите закрыть окно, нажмите на кнопку","Отправить поздравление"); 
            msgpopup.commands.append(new Windows.UI.Popups.UICommand("ok", function () {
               
            }));
 
            msgpopup.showAsync();
        };

    }]);

    //настраиваем, указываем шаблон и контроллер
    angular_app.config(function ($stateProvider) {
        $stateProvider
         .state('mainView', {
             url: '/mainView',
             templateUrl: '/views/mainView.html',
             controller: 'mainViewCtrl',
         });
    });

    //переходим на view при открытии приложения
    angular_app.constant('homeStateName', 'mainView');
    angular_app.run(function (navigationSvc) {
        navigationSvc.goHome();
    });
        
    (function () {
        var NavigationSvc = function ($q, $state, adapterSvc, homeStateName) {
            WinJS.Navigation.addEventListener('navigating', function (args) {
                var targetState = args.detail.location;
                var angularPromise = $state.go(targetState, args.detail.state);
                args.detail.setPromise(adapterSvc.toWinJSPromise(angularPromise));
            });

            this.goHome = function () {
                return adapterSvc.toAngularPromise(WinJS.Navigation.navigate(homeStateName));
            };

            this.navigateTo = function (view, initialState) {
                return adapterSvc.toAngularPromise(WinJS.Navigation.navigate(view, initialState));
            };

            this.goBack = function () {
                return adapterSvc.toAngularPromise(WinJS.Navigation.back());
            };

            this.goForward = function () {
                return adapterSvc.toAngularPromise(WinJS.Navigation.forward());
            }
        };

        angular_app.service('navigationSvc', NavigationSvc);
    }());

    angular_app.service('adapterSvc', ['$q', function ($q) {
        return {
            toAngularPromise: function (winjsPromise) {
                var deferred = $q.defer();

                winjsPromise.then(function (value) {
                    deferred.resolve(value);
                }, function (err) {
                    deferred.reject(err);
                }, function (value) {
                    deferred.notify(value);
                });

                return deferred.promise;
            },

            toWinJSPromise: function (angularPromise) {
                var signal = new WinJS._Signal();

                angularPromise.then(function (value) {
                    signal.complete(value);
                }, function (err) {
                    signal.error(err);
                }, function (value) {
                    signal.progress(value);
                });

                return signal.promise;
            }
        }
    }]);

    app.start();
})();


В этом коде мы:

  • Инициализируем библиотеки AngularJS и заставляем выполниться механизм bootstrap при загрузке страницы приложения. Подробнее как работает bootstrap в AngularJS описано в руководстве.
  • Создаем контроллерdemoViewCtrl, в котором создаем переменную и обрабатываем событие нажатия на кнопку на панели действий
  • Реализуем навигацию и загрузку представления в контейнер.

    Некоторые детали про навигацию

    Как вы знаете, в WinJS есть своя библиотека для навигации WinJS.Navigation и вы можете создавать одностраничные приложения (single page apps), где все остальные страницы подгружаются в DOM одной основной страницы, или использовать привычную модель навигации и осуществлять переходы между страницами.

    AngularJS имеет возможности навигации между представлениями в рамках одностраничного приложения, которые очень похожи на концепцию навигации в WinJS. Функции работы с навигацией доступны в виде отдельного модуля на сайте AngularJS. Популярной альтернативой модуль UI Router (мы уже установили из NuGet).

    Начав использовать AngularJS вы можете выбирать какими механизмами (WinJS или AngularJS) вы будете пользоваться в своем проекте. Единственное что надо помнить – это то, что у тебе телефона есть аппаратная кнопка Back, про которую AngularJS ничего не знает, и чтобы она работала, мы используем гибридный вариант навигации AngularJS+WinJS.


5. Запускаем приложение. Приложение должно запуститься и загрузить представление.



Заключение

Все больше технологий, которые мы привыкли видеть и использовать в веб, становятся доступны для мобильных платформ. И это просто замечательно.

Библиотеки Angular для Windows Phone

Библиотека Angular-WinJS
Исправленный файл angular.js
Пример кода: ToDoList для Windows Phone 8.1 на AngularJS

Полезные ссылки

Документация по AngularJS
Изучить курсы виртуальной академии Microsoft
Попробовать Azure бесплатно на 30 дней!
Загрузить бесплатную или пробную Visual Studio
Стать разработчиком приложений Windows Phone
Стать разработчиком приложений Windows Store