Spec-Zone.ru › Angular.js 1.6

Улучшить эту документациюОбзор концепций

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

Концепция Описание
Шаблон HTML с дополнительной разметкой
Директивы расширяют HTML с помощью пользовательских атрибутов и элементов
Модель данные, отображаемые пользователю в представлении и с которыми пользователь взаимодействует
Область видимости контекст, в котором хранится модель, чтобы контроллеры, директивы и выражения могли получить к ней доступ
Выражения доступ к переменным и функциям из области видимости
Компилятор парсит шаблон и инициализирует директивы и выражения
Фильтр форматирует значение выражения для отображения пользователю
Представление то, что видит пользователь (DOM)
Привязка данных синхронизация данных между моделью и представлением
Контроллер бизнес-логика, стоящая за представлениями
Внедрение зависимостей Создаёт и подключает объекты и функции
Инжектор контейнер для внедрения зависимостей
Модуль контейнер для различных частей приложения, включая контроллеры, сервисы, фильтры, директивы, который настраивает инжектор
Сервис многократно используемая бизнес-логика, независимая от представлений

Первый пример: привязка данных

В следующем примере мы создадим форму для расчёта стоимости счета в разных валютах.

Начнём с полей ввода для количества и стоимости, значения которых умножаются для получения общей суммы по счёту:

Попробуйте живую демонстрацию выше, а затем давайте пройдёмся по примеру и опишем, что происходит.

Это выглядит как обычный HTML с некоторыми новыми тегами. В AngularJS такой файл называется шаблоном. Когда AngularJS запускает ваше приложение, он парсит и обрабатывает эту новую разметку из шаблона с помощью компилятора. Загруженный, преобразованный и отрисованный DOM затем называется представлением.

Первый тип новой разметки — директивы. Они применяют специальное поведение к атрибутам или элементам в HTML. В примере выше мы используем атрибут ng-app, который связан с директивой, автоматически инициализирующей наше приложение. AngularJS также определяет директиву для элемента input, которая добавляет дополнительное поведение к элементу. Директива ng-model хранит/обновляет значение поля ввода в/из переменной.

Пользовательские директивы для доступа к DOM: В AngularJS единственное место, где приложение должно обращаться к DOM, — это директивы. Это важно, потому что артефакты, которые обращаются к DOM, трудно тестировать. Если вам нужно напрямую получить доступ к DOM, вы должны написать пользовательскую директиву для этого. Руководство по директивам объясняет, как это сделать.

Второй тип новой разметки — двойные фигурные скобки {{ expression | filter }}: Когда компилятор встречает эту разметку, он заменит её значением вычисленного выражения. Выражение в шаблоне — фрагмент кода, похожий на JavaScript, который позволяет AngularJS читать и записывать переменные. Обратите внимание, что эти переменные не являются глобальными переменными. Точно так же, как переменные в функции JavaScript существуют в области видимости, AngularJS предоставляет область видимости для переменных, доступных выражениям. Значения, хранящиеся в переменных в области видимости, в остальной части документации называются моделью.

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

Важный момент в примере — AngularJS обеспечивает живую привязку: при изменении значений ввода значения выражений автоматически пересчитываются, а DOM обновляется с их значениями. Концепция, стоящая за этим, — двухсторонняя привязка данных.

Добавление логики пользовательского интерфейса: контроллеры

Добавим немного больше логики в пример, который позволит вводить и вычислять стоимость в разных валютах, а также оплачивать счёт.

Что изменилось?

Во-первых, появился новый файл JavaScript, содержащий контроллер. Точнее, файл определяет конструкторскую функцию, которая будет использоваться для создания фактического экземпляра контроллера. Цель контроллеров — предоставлять переменные и функциональность выражениям и директивам.

Помимо нового файла с кодом контроллера, мы также добавили директиву ng-controller в HTML. Эта директива сообщает AngularJS, что новый InvoiceController отвечает за элемент с директивой и все дочерние элементы. Синтаксис InvoiceController as invoice сообщает AngularJS, что нужно создать контроллер и сохранить его в переменной invoice в текущей области видимости.

Мы также изменили все выражения на странице, чтобы читать и писать переменные внутри этого экземпляра контроллера, добавив префикс invoice.. Доступные валюты определены в контроллере и добавлены в шаблон с помощью ng-repeat. Так как контроллер содержит функцию total, мы также можем привязать результат этой функции к DOM с помощью {{ invoice.total(...) }}.

Опять же, эта привязка является живой, т.е. DOM будет автоматически обновляться всякий раз, когда меняется результат функции. Кнопка для оплаты счета использует директиву ngClick. Это вычислит соответствующее выражение при нажатии на кнопку.

В новом файле JavaScript мы также создаём модуль, в котором регистрируем контроллер. Мы поговорим о модулях в следующей части.

Следующий график показывает, как всё работает вместе после того, как мы представили контроллер:

Бизнес-логика, независимая от представления: сервисы

Сейчас InvoiceController содержит всю логику нашего примера. По мере роста приложения хорошей практикой является перемещение логики, независимой от представления, из контроллера в сервис, чтобы её можно было повторно использовать другими частями приложения. Позже мы могли бы изменить этот сервис для загрузки обменных курсов с веб-сайта, например, вызвав API обменных курсов Fixer.io, не изменяя контроллер.

Давайте перепишем наш пример и переместим конвертацию валют в сервис в другой файл:

Что изменилось?

Мы переместили функцию convertCurrency и определение существующих валют в новый файл finance2.js. Но как контроллер получает доступ к теперь отделённой функции?

Здесь на помощь приходит внедрение зависимостей. Внедрение зависимостей (DI) — это шаблон проектирования программного обеспечения, который описывает, как создаются объекты и функции, и как они получают доступ к своим зависимостям. Всё в AngularJS (директивы, фильтры, контроллеры, сервисы и т.д.) создаётся и подключается с помощью внедрения зависимостей. В AngularJS контейнер DI называется инжектором.

Для использования DI нужен место, где регистрируются все взаимодействующие вещи. В AngularJS эту роль выполняют модули. При запуске AngularJS он использует конфигурацию модуля с именем, определённым директивой ng-app, включая конфигурацию всех модулей, от которых зависит этот модуль.

В примере выше: Шаблон содержит директиву ng-app="invoice2". Это сообщает AngularJS использовать модуль invoice2 в качестве основного модуля для приложения. Фрагмент кода angular.module('invoice2', ['finance2']) указывает, что модуль invoice2 зависит от модуля finance2. Благодаря этому AngularJS использует сервис InvoiceController и сервис currencyConverter.

Теперь, когда AngularJS знает обо всех частях приложения, ему нужно их создать. В предыдущем разделе мы видели, что контроллеры создаются с помощью конструкторской функции. Для сервисов существуют разные способы задания их создания (см. руководство по сервисам). В примере выше мы используем анонимную функцию в качестве фабричной функции для сервиса currencyConverter. Эта функция должна возвращать экземпляр сервиса currencyConverter.

Возвращаясь к первоначальному вопросу: Как контроллер InvoiceController получает ссылку на функцию currencyConverter? В AngularJS это делается путём простого определения аргументов в конструкторской функции. Благодаря этому инжектор может создавать объекты в правильном порядке и передавать ранее созданные объекты в фабрики объектов, которые от них зависят. В нашем примере контроллер InvoiceController имеет аргумент с именем currencyConverter . Благодаря этому AngularJS знает о зависимости между контроллером и сервисом и вызывает контроллер с экземпляром сервиса в качестве аргумента.

Последнее, что изменилось в примере между предыдущим и текущим разделом, — это то, что мы теперь передаём массив в функцию module.controller вместо обычной функции. Массив сначала содержит имена зависимостей сервиса, которые необходимы контроллеру. Последний элемент в массиве — конструкторская функция контроллера. AngularJS использует этот синтаксис массива для определения зависимостей, чтобы DI также работала после минификации кода, который, скорее всего, переименует имя аргумента конструкторской функции контроллера на более короткое имя, например, на a.

Доступ к бэкенду

Завершим наш пример, получив обменные курсы из API обменных курсов Fixer.io. Следующий пример показывает, как это делается с помощью AngularJS:

Что изменилось? Наш currencyConverter сервис модуля finance теперь использует $http, встроенный сервис AngularJS для доступа к серверному бэкенду. $http — это оболочка вокруг XMLHttpRequest и JSONP-транспортов.

© 2010–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.6.9/docs/guide/concepts

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API