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

в 16:43, , рубрики: AngularJS, javascript, метки: , ,

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>), атрибут (<div my-directive="exp"> </div>), в классе (<div class="my-directive: exp;"></div>) или в комментарии (<!-- directive: my-directive exp -->). Это зависит от того, как конкретная директива была разработана.

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

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

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js