Контроллеры AngularJS с примером ng-Controller

⚡ Умное резюме

Контроллер в AngularJS содержит бизнес-логику экрана. Он получает данные через объект области видимости, обрабатывает их и возвращает результат в представление.ping Разметка презентации, свободная от логики приложения.

  • 🎯 Основные обязанности: Контроллер заполняет объект области видимости и предоставляет доступ к методам представления; он не манипулирует DOM.
  • 🔗 Проводка: Директива ng-controller связывает именованный контроллер с элементом, предоставляя этому элементу и его дочерним элементам доступ к области видимости контроллера.
  • 🔁 Двусторонняя переплетка: ng-model связывает поле формы со свойством области видимости, поэтому изменения в представлении обновляют контроллер, и наоборот.
  • 🧩 Методы: Функции, прикрепленные к области видимости, разделяют отдельные логические блоки и могут быть вызваны непосредственно из выражений представления.
  • 🏷️ Синтаксис controllerAs: Создание псевдонима для контроллера и привязка к нему. this Устраняет неоднозначность, когда контроллеры вложены друг в друга.
  • 📁 Разделение: Перемещение контроллеров в отдельный файл app.js позволяет сохранить независимость уровня представления от уровня логики.

Контроллеры AngularJS с использованием ng-controller

Что такое контроллер в AngularJS?

A Контроллер В AngularJS данные берутся из представления, обрабатываются, а затем передаются в представление, которое отображается конечному пользователю. Контроллер содержит основную бизнес-логику. Он использует модель данных, выполняет необходимую обработку, а затем передает результат в представление.

⚠️ Примечание к версии: Поддержка AngularJS (ветка 1.x) завершилась 31 декабря 2021 года, и дальнейшие обновления безопасности не выпускаются. Приведенные ниже концепции по-прежнему применимы к устаревшим приложениям; в современном Angular ту же роль выполняет класс компонента, а не контроллер.

Понимание того, что такое контроллер, оставляет открытым один вопрос: как он на самом деле взаимодействует с представлением? Ответ на этот вопрос будет дан в следующем разделе.

Что делает контроллер с точки зрения Angular?

Ниже приведено простое описание работы контроллера AngularJS:

Работа контроллера AngularJS
Работа контроллера AngularJS
  • Основная ответственность контроллера — управлять данными, которые передаются в представление. Область видимости и представление имеют двустороннюю связь.
  • Свойства представления и события могут вызывать функции в области видимости. Приведённый ниже фрагмент кода демонстрирует это. функция ($ область действия) объявлен с контроллером плюс внутренняя функция, возвращающая $scope.firstName и $scope.lastName присоединился. В AngularJSФункция, определенная как переменная, является методом.

Работа контроллера AngularJS

  • Данные передаются от контроллера к области видимости, а затем туда и обратно между областью видимости и представлением.
  • Область видимости (scope) предоставляет доступ к модели представлению. Модель может быть изменена с помощью методов, определенных в области видимости, которые запускаются событиями из представления.
  • Контроллеры не следует использовать для манипулирования DOM. Это задача контроллеров. Директивы.
  • Наилучшей практикой является создание контроллеров на основе их функциональности. Если у вас есть форма ввода, для которой нужен контроллер, создайте контроллер с именем «контроллер формы».

Разобравшись в механизме, в следующем разделе мы создадим контроллер с нуля.

Как создать базовый контроллер в AngularJS

Ниже описаны шаги по созданию контроллера в AngularJS.

Шаг 1) Создайте базовую HTML-страницу.

Перед созданием контроллера необходимо подготовить базовую HTML-страницу. Приведённый ниже фрагмент кода представляет собой простую страницу под названием «Регистрация на мероприятие», которая ссылается на... Bootstrap и AngularJS.

Создайте базовый контроллер в AngularJS

  1. Ссылки на Bootstrap CSS-таблица стилей, используемая вместе с Bootstrap библиотека.
  2. Ссылка на библиотеку AngularJS. Все дальнейшие действия с AngularJS выполняются через этот файл.
  3. Ссылка на Bootstrap библиотека, которая делает некоторые элементы управления отзывчивыми.

⚠️ Исправление: В исходном коде загружался jQuery, и указывалось, что AngularJS зависит от него. Это не так. AngularJS поставляется с jqLite, встроенным подмножеством API jQuery, и обновляется до полной версии jQuery только в том случае, если jQuery загружен. до Это. Ссылка удалена.

Шаг 2) Проверьте файлы и файловую структуру.

Создайте базовый контроллер в AngularJS

  1. Файлы, как и в любом обычном веб-приложении, разделены на две папки: «css» для таблиц стилей и «lib» для JavaСценарий файлы.
  2. Файл bootstrap.css находится в папке css и определяет внешний вид и функциональность сайта.
  3. angular.js — это основная библиотека, загруженная с сайта AngularJS и хранящаяся в папке lib.
  4. В файле app.js будет содержаться код контроллеров.

Шаг 3) Используйте код AngularJS для отображения результатов.

Цель состоит в том, чтобы отображать слова «AngularJS» как в виде обычного текста, так и в текстовом поле при открытии страницы в браузере.

Создайте базовый контроллер в AngularJS

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
Tutorial Name : <input type="text" ng-model="tutorialName"><br>
This tutorial is {{tutorialName}}
</div>

<script src="lib/angular.js"></script>
<script>
var app = angular.module('DemoApp', []);

app.controller('DemoController', ['$scope', function($scope) {
  $scope.tutorialName = "AngularJS";
}]);
</script>
</body>
</html>

Code Объяснение:

  1. нг-приложение Этот элемент помечается как корневой элемент приложения AngularJS. Атрибуты имеют префикс. нг- являются встроенными директивами. «DemoApp» — это название приложения.
  2. Дифференциал содержит нг-контроллер с именем «DemoController», что дает этому элементу и всему, что находится внутри него, доступ к области видимости контроллера.
  3. нг-модель создает привязку модели, связывая текстовое поле «Название учебного пособия» со свойством области видимости. tutorialName.
  4. Модуль DemoApp создается, и контроллер присваивает ему значение по умолчанию «AngularJS». tutorialName.

⚠️ Исправления внесены. В первоначальном объявлении было указано: chrset="UTF 8", который не является ни допустимым атрибутом, ни допустимым именем кодировки, и загрузил AngularJS дважды — один раз с CDN и один раз с другого источника. lib/angular.jsДвойная загрузка библиотеки приводит к повторной регистрации модульной системы и непредсказуемому поведению. Аннотация массива зависимостей ['$scope', function($scope){…}] Также было добавлено, без чего контроллер перестаёт работать в момент минификации файла.

Выход:

Создайте базовый контроллер в AngularJS

Так как tutorialName Если свойству присвоено значение «AngularJS», это значение отображается в текстовом поле и в строке обычного текста. Для демонстрации достаточно одного свойства; реальные контроллеры обычно также предоставляют информацию о поведении, которая рассматривается в следующем разделе.

Как определить методы в контроллерах AngularJS

Обычно в контроллере определяют несколько методов для разделения бизнес-логики. Если бы контроллеру нужно было сложить два числа и выполнить подпрограмму, это было бы нецелесообразно.tracЕсли речь идёт о двух числах, то для каждой операции следует создать отдельный метод.

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

Определение методов в контроллерах AngularJS

<!-- The head and library references are unchanged from Step 3 -->
<div ng-app="DemoApp" ng-controller="DemoController">
Tutorial Name : <input type="text" ng-model="tutorialName"><br>
This tutorial is {{tName()}}
</div>

<script>
var app = angular.module('DemoApp', []);

app.controller('DemoController', ['$scope', function($scope) {
  $scope.tutorialName = "AngularJS";

  // A method on the scope, callable from the view as tName()
  $scope.tName = function() {
    return $scope.tutorialName;
  };
}]);
</script>

Code Объяснение:

  1. Функция присоединяется к объекту области видимости в качестве члена. tName. Она возвращает текущее значение tutorialName.
  2. Представление вызывает метод с {{tName()}}Скобки имеют значение: без них выражение выводит саму функцию, а не её результат.

⚠️ Исправление: исходный метод читался $scope.tName = function() { return $scope.tName; };Эта функция возвращает саму себя, а не название учебного пособия, поэтому на странице отображалось тело функции вместо текста. Теперь она возвращает $scope.tutorialName.

Выход:

Определение методов в контроллерах AngularJS

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

Контроллер AngularJS с примером ng-Controller

В приведенном выше примере «HelloWorld» вся функциональность размещена в одном файле. Теперь пришло время перенести код контроллера в отдельный файл.

Шаг 1) В файле app.js добавьте следующий код для вашего контроллера.

Контроллер AngularJS с ng-Controller

angular.module('app', [])
  .controller('HelloWorldCtrl', ['$scope', function($scope) {
    $scope.message = "Hello World";
  }]);

Приведенный выше код делает следующее:

  1. Определяет модуль под названием «app», который содержит контроллер.
  2. Создает контроллер с именем «HelloWorldCtrl», который отображает сообщение «Hello World».
  3. Использует объект scope для передачи информации из контроллера в представление, в данном случае — переменной с именем message.

Шаг 2) В файле Sample.html добавьте div, содержащий директиву ng-controller и ссылку на переменную-член. messageНе забудьте добавить ссылку на файл app.js, в котором находится исходный код контроллера.

Контроллер AngularJS с ng-Controller

<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<h1> Guru99 Global Event</h1>
<div class="container">
<div ng-controller="HelloWorldCtrl">{{message}}</div>
</div>

<script src="lib/angular.js"></script>
<script src="app.js"></script>
</body>
</html>

⚠️ Исправление: Файл app.js должен быть загружен. после angular.js, поскольку он вызывает angular.moduleОригинальная версия также дважды загружала библиотеку и содержала то же самое. chrset опечатка.

Выход:

Контроллер AngularJS с ng-Controller

Во всех приведенных примерах свойства чтения и записи указаны непосредственно. $scopeВ разделе ниже рассматривается альтернативный вариант, который рекомендует команда AngularJS.

Как использовать синтаксис controllerAs в AngularJS

Прямая привязка к $scope Работает, но становится неоднозначным, как только контроллеры вложены друг в друга. Выражение представления, например, такое: {{name}} Не даёт ни малейшего представления о том, какой контроллер принадлежит кому. nameПоскольку дочерние области видимости наследуют от родительских областей видимости прототипически, вложенный контроллер, который записывает данные в унаследованный примитив, незаметно создает свою собственную теневую копию. controllerAs Синтаксис устраняет обе проблемы, присваивая каждому контроллеру псевдоним.

Шаг 1) Создайте псевдоним для контроллера в представлении, используя... as Затем добавьте этот псевдоним к каждому ключевому слову.

Шаг 2) Внутри контроллера прикрепите свойства к this а не $scope.

<div ng-controller="DemoController as demo">
Tutorial Name : <input type="text" ng-model="demo.tutorialName">
This tutorial is {{demo.tutorialName}}
</div>

<script>
app.controller('DemoController', function() {
  // 'vm' is captured so nested functions keep the right reference
  var vm = this;
  vm.tutorialName = "AngularJS";

  vm.tName = function() {
    return vm.tutorialName;
  };
});
</script>

За этим следуют три преимущества. Связи становятся самодокументируемыми, потому что demo.tutorialName указывает имя владельца. Вложенные контроллеры перестают конфликтовать, поскольку родительский контроллер имеет псевдоним. outer и ребенок, принявший псевдоним. inner оба могут раскрыть nameЗначения также связываются через объект, а не через простой примитив, что позволяет обойти ограничения.ping Ловушка, при которой изменения в дочернем элементе никогда не достигают родительского.

Примечание: Наконечник: захват this в переменную, например vm в верхней части контроллера. Внутри функции обратного вызова, this Это относится к чему-то совершенно другому, и захваченная ссылка обеспечивает корректность привязки.

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

Контроллер против сервиса в AngularJS

Начинающие разработчики часто перегружают контроллер работой, которая должна выполняться в сервисе. Разница заключается в сроке службы и возможности повторного использования: контроллер существует только пока его представление отображается на экране, тогда как сервис — это синглтон, который существует на протяжении всего существования приложения.

Аспект Контроллер Cервис
Вечного пользования Создано и разрушено с учетом вида Единый экземпляр для всего приложения
Цель Подготовьте данные для одного представления. Общая логика, состояние и вызовы сервера
Многоразовый Нет, привязано к его точке зрения. Да, инъекции можно делать в любое место.
Сохраняет состояние между представлениями Нет, состояние теряется при навигации. Да, государство продолжает существовать.
Типичное содержание Свойства области видимости и методы отображения HTTP-запросы, кэширование, бизнес-правила

Контроллеры должны быть максимально простыми. Если двум контроллерам необходима одна и та же логика, или если значение должно сохраняться при переходе между представлениями, переместите его в сервис и внедрите этот сервис там, где он необходим. Практический тест — спросить себя, будет ли код иметь смысл при закрытом текущем экране. Если ответ положительный, то его следует поместить в сервис.

Часто задаваемые вопросы (FAQ)

Да. AngularJS создает отдельный экземпляр и отдельную область видимости для каждого элемента, содержащего директиву. Экземпляры не разделяют состояние, поэтому изменение в одном не отразится на другом.

Объявите это в маршруте, когда контроллер принадлежит целому представлению, загружаемому с помощью маршрутизацияИспользуйте `ng-controller` для компонента, который отображается на странице независимо от текущего маршрута. Никогда не объявляйте оба компонента, иначе контроллер будет выполняться дважды.

Используйте аннотацию массива, перечисляя имена зависимостей в виде строк перед функцией. Минификаторы переименовывают аргументы функций, но никогда не переименовывают строковые литералы, поэтому инжектор по-прежнему корректно разрешает $scope и любые сервисы.

Да. AI Вспомогательные функции генерируют привязки модуля, контроллера и области видимости на основе простого описания экрана. Всегда проверяйте аннотацию зависимости, поскольку сгенерированный код часто её опускает.

Инструменты искусственного интеллекта переписывают назначения области видимости в виде свойств захваченной переменной виртуальной машины и добавляют префикс к каждой соответствующей привязке представления с указанием псевдонима. RevПросматривайте вызовы $watch и обработчики событий вручную, поскольку для этого по-прежнему требуется объект scope.

Подведем итог этой публикации следующим образом: