Пользователь
0,0
рейтинг
5 августа 2012 в 20:43

Разработка → AngularJS — фреймворк для динамических веб-приложений от Google

AngularJS создан для тех разработчиков, которые считают, что декларативный стиль лучше подходит для создания UI, а императивный — для написания бизнес-логики.

Дзен Angular


  • Хорошо отделять манипуляцию DOM-ом от логики работы приложения. Это существенно улучшает тестируемость кода.
  • Хорошо считать, что автоматизированное тестирование приложения настолько же важно, насколько и написание самого приложения. Тестируемость очень сильно зависит от того, как структурирован код.
  • Хорошо отделять разработку клиентской части от серверной. Это позволяет вести разработку параллельно и улучшает повторное использование на обеих сторонах.
  • Хорошо, когда фреймворк ведет разработчика по всему циклу разработки приложения: от проектирования UI через написание бизнес-логики к тестированию.
  • Хорошо, когда распространенные задачи становятся тривиальными, а сложные — упрощаются.


AngularJS представляет собой комплексный фреймворк. В стандартной поставке он предоставляет следующие возможности:
  • Все, что вам нужно для создания CRUD-приложений: data-binding, базовые директивы для шаблонов, валидация форм, роутинг, deep linking, повторное использование компонентов, dependency injection, инструменты для взаимодействия с серверными (RESTful) источниками данных.
  • Все, что вам нужно для тестирования: средства для модульного тестирование, end-to-end тестирования, mock-и.
  • Шаблон типового приложения, включающего в себя структуру каталогов и тестовые скрипты.


AngularJS разрабатывается сотрудниками Google и используется, как минимум, в одном сервисе Google — DoubleClick.



Примеры


Простенькая todo-шка
<div ng-app>
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
    <span>{{remaining()}} of {{todos.length}} remaining</span>
    [ <a href="" ng-click="archive()">archive</a> ]
    <ul class="unstyled">
      <li ng-repeat="todo in todos">
        <input type="checkbox" ng-model="todo.done">
        <span class="done-{{todo.done}}">{{todo.text}}</span>
      </li>
    </ul>
    <form ng-submit="addTodo()">
      <input type="text" ng-model="todoText"  size="30" placeholder="add new todo here">
      <input class="btn-primary" type="submit" value="add">
    </form>
  </div>
</div>
​

function TodoCtrl($scope) {
  $scope.todos = [
    {text:'learn angular', done:true},
    {text:'build an angular app', done:false}];

  $scope.addTodo = function() {
    $scope.todos.push({text:$scope.todoText, done:false});
    $scope.todoText = '';
  };

  $scope.remaining = function() {
    var count = 0;
    angular.forEach($scope.todos, function(todo) {
      count += todo.done ? 0 : 1;
    });
    return count;
  };

  $scope.archive = function() {
    var oldTodos = $scope.todos;
    $scope.todos = [];
    angular.forEach(oldTodos, function(todo) {
      if (!todo.done) $scope.todos.push(todo);
    });
  };
}

В действии можно посмотреть на главной странице angularjs.org. Там же представлен еще ряд примеров:
  • «The Basics» — простенькая иллюстрация databinding.
  • «Add Some Control» — todo-шка, код которой я привел здесь.
  • «Wire up a Backend» — простое приложение создания/хранения/редактирования записей с роутингом и хранением данных в mongolab.
  • «Create Components» — создание повторно используемых компонентов.

Еще примеры:
  • todo (демо, код) из todomvc — заодно можно посравнивать с другими фреймворками;
  • builtwith.angularjs.org: 18 (на момент написания поста) приложений, для большинства из которых доступен исходный код;
  • AngularUI — разные фильтры и директивы (во многом UI-шные) от сторонних разработчиков.


Основные понятия AngularJS


Директивы

На директивах держится практически вся декларативная часть AngularJS. Именно они используются для обогащения синтаксиса HTML. В процессе компиляции DOM директивы берутся из HTML и исполняются. Директивы могут добавить какое-то новое поведение и/или модифицировать DOM. В стандартную поставку входит достаточно большое количество директив для построения веб приложений. Но ключевой особенностью является возможность разработки своих директив, за счет чего HTML может быть превращен в DSL.

Директивы именуются с помощью lowerCamelCase, например, ngBind. При использовании директиву необходимо именовать в нижнем регистре с использованием в качестве разделителя одного из спец символов: :, -, или _. По желанию для получения валидного кода можно использовать префиксы x- или data-. Примеры: ng:bind, ng-bind, ng_bind, x-ng-bind и data-ng-bind.

Директивы могут использоваться как элемент (<my-directive></my-directive>), атрибут (), в классе () или в комментарии (). Это зависит от того, как конкретная директива была разработана.

Подробнее о директивах в руководстве разработчика.

Scope-ы

Scope — это объект, имеющий отношение к модели в приложении. Он является контекстом выполнения для выражений. Scope-ы выстраиваются в иерархическую структуру, похожую на DOM. При этом они наследуют свойства от своих родительских scope-ов.

Scope-ы являются как бы «клеем» между контроллером и представлением. В процессе выполнения фазы связывания шаблона директивы устанавливают наблюдение ($watch) за выражениями в рамках scope. $watch дает директивам возможность реагировать на изменения для отображения обновленного значения или каких-либо других действий. И контроллеры, и директивы имеют ссылку на scope, но не имеют ссылок друг на друга. Так контроллеры изолируются от директив и от DOM-а. За счет этого возрастают возможности по тестированию приложения.

Подробнее о scope-ах в руководстве разработчика.

Сервисы

Сервисы — singleton-ы, выполняющие какую-либо конкретную задачу, которая является общей для всех или конкретного веб-приложения. Например, $http сервис, который является оберткой над XMLHttpRequest. Несколько примеров других сервисов (полный список смотрите в документации):
  • $compile — компиляция HTML-строки или части DOM-а в шаблон, связывание шаблона с конкретным scope-ом;
  • $cookies — предоставляет доступ на чтение/запись к cookies.
  • $location — работа с адресной строкой
  • $resource — фабрика по созданию ресурсных объектов, предназначенных для взаимодействия с серверными (RESTful) источниками данных;


Для использования сервиса необходимо указать его как зависимость для контроллера, другого сервиса, директивы и т.п. AngularJS позаботится обо всем остальном — создании, разрешении зависимостей и т.п.

Подробнее о сервисах в руководстве разработчика.

Фильтры

Фильтры предназначены для форматирования данных перед отображением их пользователю, а также фильтрации элементов в коллекциях. Примеры фильтров (полный список можно посмотреть в документации): currency, date, orderBy, uppercase. Использование фильтров достаточно традиционно: {{ expression | filter1 | filter2 }}

Подробнее о фильтрах в руководстве разработчика.

Модули

Приложения в AngularJS не имеют основного исполняемого метода. Вместо этого модуль выполняет роль декларативного описания того, как приложение должно быть загружено. Благодаря этому, например, при написании сценариев тестирования можно подгрузить дополнительные модули, которые переопределят какие-то настройки, облегчая тем самым комплексное (end-to-end) тестирование.

Подробнее о модулях в руководстве разработчика.

Тестирование

Как пишут разработчики, для тестирования они сделали очень много в AngularJS, поэтому уже ничего не может извинить вас, если вы не будете тестировать свое приложение :)

Пример тестового e2e сценария:
describe('Buzz Client', function() {
it('should filter results', function() {
  input('user').enter('jacksparrow');
  element(':button').click();
  expect(repeater('ul li').count()).toEqual(10);
  input('filterText').enter('Bees');
  expect(repeater('ul li').count()).toEqual(1);
});
});


Подробнее о модульном тестировании и e2e тестировании в руководстве разработчика.

AngularJS Batarang


Это расширение для Chrome, которое облегчает отладку AngularJS приложений. Позволяет работать с иерархией scope-ов, дает возможность профилирования приложения, визуализирует зависимости между сервисами, отображает содержимое scope-ов на странице элементов, позволяет выводить и менять значения в scope из консоли. Хорошее текстовое описание на странице в github. Хорошее видео на youtube.

Что еще почитать


Артем Андреев @aav
карма
44,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (36)

  • +1
    Зачем они применили нестандартные атрибуты я не очень понял. Не XML же.
    • +4
      А что в этом плохого? HTML это не XML (да да ваш К.О.), следовательно нам нет необходимости передавать избыточный контент только для того что бы HTML был XML совместимым. Или вы собираетесь свои страницы xml парсером утюжить?
      • +3
        так-то есть стандартные атрибуты data- бери их и делай что хочешь.

        А про XML — в XML как раз «делай что хочешь, только уведоми».
        • 0
          При использовании AngularJS можно все аттрибуты фреймворка писать с префиксом data, это поддерживается.
          • 0
            это отлично, только официальная демонстрация даёт плохой пример.
            • +1
              Скорее они не видят в этом настолько серьезной проблемы и серьезно относятся к тому, что на базе HTML и AngularJS можно сделать DSL для своего приложения. Потому, возможно, для себя не видят смысла в полумерах, если уж собираются нестандартные элементы использовать.
    • 0
      Их можно использовать с префиксом «data-», если очень хочется.
    • 0
      Со временем Гуголь их сделает стандартными. W3C долго сопротивляться не сможет. :-).
  • +2
    Лично меня раздражают дополнительные аттрибуты в html / шаблонах. Сперва мы уходим от всяких onclick, onsubmut и т.д., а теперь возвращаемся? Да еще и используется куча невалидных аттрибутов.
    Как по мне стоит все же придерживаться стиля Backbone.js
    • 0
      опыт mail.ru, впрочем, показал, что onclick, например, это вовсе даже и не плохо.
    • 0
      Куча невалидных атрибутов, как писалось в статье и комментариях выше, легко превращается в кучу валидных.

      А возвращаемся мы не к тому же самому, а к немного другому более гибкому варианту, т.к. и те которые есть директивы — мощнее и гибче, да и свои можно разрабатывать.

      > Как по мне стоит все же придерживаться стиля Backbone.js
      Само собой, дело вкуса. Но, как по мне :), так у AngularJS все лаконичнее, boilerplate кода меньше.
  • 0
    А мне понравилось, идея и воплощение интересные. Думаю попробую в следующем проекте.
  • 0
    Подскажите, где почитать о том как в подобных приложениях (где практически вся логика на клиенте) реализовать аутентификацию и авторизацию?
    • 0
      я нашёл в сети только это решение www.espeo.pl/2012/02/26/authentication-in-angularjs-application
    • +1
      А как реализуется аутенфикация и авторизация у клиентских приложений? Посредствам API на серверной стороне. Например на запрос по логину и паролю, в случае успеха разумеется, приходит рандомный токен, который вы должны передавать в заголовках при каждом запросе к серверу. Так же через серверный API можно проверять есть ли у пользователя разрешение на выполнение определенных действий.
      • 0
        А token хранить в куках?
        • 0
          Мне нравится идея с хранением этого добра в LocalStorage. Если на сайте нету возможности произвести какую-либо инъекцию кода, то и получить данные из LocalStorage не выйдет. Быть может я и не прав, у меня было не так много проектов где этот вопрос встречался.
          • +3
            Против инъекций есть http-only cookies.
            • 0
              Они передаются в ajax-запросах?
              • 0
                Конечно
                • 0
                  Что вы думаете об архитектуре API Вконтакте?
                  Если пойти по такому пути, с прицелом на то, что в дальнейшем API также будет использоваться в iOS-приложении?
                  • 0
                    Если это конкретно мне — я не работал с апи вконтакте)
                    Но, посмотрев доки, могу сказать (может я и ошибаюсь) — оно довольно неудобное
                    • 0
                      это вопрос ко всем.
                      Тогда уточняю вопрос чьё API можно взять за образец?
                      • 0
                        добавил по этой теме отдельный вопрос habrahabr.ru/qa/22392/
                      • +1
                        Ну во-первых можно почитать статьи, например www.ibm.com/developerworks/webservices/library/ws-restful/

                        Недавно работал с апи highrise, ничего сверхъестественного, но там и не нужно, все просто и удобно. Думаю есть примеры и получше, с более сложными моделями данных
  • +2
    Столько JS-велосипедов в последнее время, не перестаёшь удивляться.
  • 0
    Как-то много всего наворотили. Как бы в этом всем не погрязнуть. Опять свой forEach… зачем…
    Почему $scope это не this? Или this там еще для чего то можно использовать?
    Ну с другой стороны не надо писать var self = this;. Но не знаю… не уверен… надо пробовать…
    • 0
      Честно говоря, я не знаю точных ответов на Ваши вопросы. Просто мои мысли.

      По forEach: подозреваю это следствие позиционирования библиотеки как комплексной, предоставляющей сразу большинство инструментов, необходимых для разработки, без внешних зависимостей. Например, angular.element вернет Вам по умолчанию свою jquery-совместимую облегченную обертку, но если Вы подключали jQuery — получите полноценный jQuery объект.

      По this и $scope: разница будет на уровне конструктора контроллера.
      «Previous versions of Angular (pre 1.0 RC) allowed you to use this interchangeably with the $scope method, but this is no longer the case. Inside of methods defined on the scope this and $scope are interchangeable (angular sets this to $scope), but not otherwise inside your controller constructor.»
  • 0
    Показательно то, что разработчики Google предпочли хостить этот проект на GitHub, а не на собственном Google Code.
    • 0
      Ну я думаю это были не одни и те же разработчики, и я думаю, все понимают, что гитхаб гораздо удобней
      • 0
        и google code закрывается, кажется
        • 0
          Закрыли Google Code Search, а с Google Code всё в порядке.
      • 0
        GitHub социальнее. Думаю для этого проекта это большой плюс.
        • 0
          Ну помимо этого он еще и просто удобнее, я имею ввиду гуй
          • 0
            Ну и это тоже :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.