Spec-Zone.ru › Angular.js 1.5

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

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

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

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

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

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

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

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

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

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

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

Применённое к примеру выше, разметка направляет Angular на "взятие данных из полей ввода и их перемножение".

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

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

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

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

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

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

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

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

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

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

На следующем рисунке показано, как все работает вместе после введения контроллера:

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

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

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

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

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

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

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

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

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

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

Благодаря этому Angular знает о зависимости между контроллером и сервисом и вызывает контроллер с экземпляром сервиса в качестве аргумента.

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

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

Давайте закончим наш пример, получив обменные курсы из API Yahoo Finance. Следующий пример демонстрирует, как это делается с Angular:

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

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

Spec-Zone.ru

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