Part I of this tutorial (back-end) can be viewed here.

Шаг 5 - Создайте index.html

В этом примере мы будем использовать шаблон Bootstrap 4. В голове у нас есть теги CDN для Bootstrap 4, jQuery, Tether.io и Font Awesome. Font Awesome - это библиотека значков, которую мы используем вместо Glyphicons, которые больше не поставляются с Bootstrap. Имейте в виду, что тег Font Awesome CDN уникален, и для его создания у вас должна быть учетная запись Font Awesome, но создать учетную запись можно бесплатно. Мы также включаем наш собственный файл CSS, к которому мы вернемся в конце учебника. ** ПРИМЕЧАНИЕ. Я изменил файлы JavaScript, чтобы они соответствовали лучшим практикам. Я не обновлял файлы HTML, но все, что вам нужно сделать, это добавить имя контроллера к любым ссылкам на переменные контроллера (например, OpenController.data.tickets вместо просто data.tickets). Основная причина изменения заключается в том, что добавление переменных к объекту $ scope является плохой практикой и снижает удобочитаемость. **

Наиболее важным здесь является атрибут ng-app = ”halp-desk”, который мы прикрепили к тегу html.

Далее мы настраиваем тело. Тег ‹div ng-view id =” main ”› ‹/div› - это то место, где мы будем отображать наши две «страницы» (открытые заявки и заархивированные заявки). Затем мы включаем все наши клиентские файлы JavaScript в нижнюю часть тела, включая angular.js и angular-route.js, которые мы установили вместе с Bower.

Шаг 6 - Создайте экземпляры клиентских маршрутов

Теперь давайте посмотрим на app.js. Здесь мы будем создавать экземпляры наших клиентских маршрутов. У нас будет две страницы: страница открытых заявок, которая является целевой страницей, и страница заархивированных заявок. Когда клиент запрашивает маршрут «/ open», мы возвращаем open.html, который будет отображаться в ‹div ng-view id =” main ”› ‹/div›. Когда клиент запрашивает маршрут ‘/ archive’, мы возвращаем archive.html, который будет отображаться в ‹div ng-view id =” main ”› ‹/div›, заменяя любой контент, который там был. Если клиент запрашивает любой маршрут, кроме этих двух, мы перенаправляем на целевую страницу - open.html.

Шаг 7 - Создайте Фабрику

Наша фабрика будет содержать все запросы к серверу в виде функциональных выражений. При вызове они отправят запрос на сервер и вернут ответ с сервера. Это должно выглядеть довольно знакомо, так как именно так мы спроектировали маршруты на сервере. Запросы GET не принимают никаких аргументов, а отправляют запрос GET на сервер и возвращают ответ от сервера - либо открытые билеты, либо заархивированные билеты. Для отправки и удаления запросов POST, а также для запроса PUT требуется аргумент билета для публикации в базе данных.

Шаг 8 - Создайте представление и контроллер открытых заявок

Мы начинаем представление Open Tickets с навигационной панели Bootstrap. Обратите внимание, что ссылка «Открыть» относится к «# / open», который был определен выше в шаге 6. То же самое для ссылки «Архив».

Затем мы создаем область содержимого, состоящую из одного внешнего контейнера и строки с двумя столбцами. Во внешний контейнер мы добавляем атрибут ng-controller = ”OpenController”, который будет обрабатывать любые вызовы функций для данных GET, POST или UPDATE.

Первый столбец - это наша форма для отправки запроса в службу поддержки. При нажатии кнопки отправки данные тикета отправляются в функцию OpenController submitTicket. У нас есть четыре поля ввода для сбора содержимого, необходимого для запроса POST к базе данных. Остальные два - архив и статус - всегда будут иметь значение false и true соответственно при создании новой заявки. На самом деле я не использовал свойство status для этого руководства, но для более продвинутых функций, поэтому вы можете игнорировать его в этом руководстве.

Во втором столбце мы отображаем билеты. Вы можете игнорировать вызов функции resolveTicket - он соответствует свойству status и не используется в этом руководстве. Мы используем атрибут ng-repeat для отображения всех билетов в объекте $ scope.data, к которому мы скоро вернемся. Каждая ссылка на {{ticket.PROPERTY}} ссылается на объект $ scope.data. В строке 52 вы можете увидеть условное выражение, которое определяет имя класса, которое влияет на стиль. Между тегами div есть еще одно условие для отображения статуса заявки. В строках 56–58 приведены примеры использования значков Font Awesome, каждый из которых связан с вызовом функции для удаления или архивирования заявки.

Теперь посмотрим на контроллер. Первое, что нам нужно сделать, это создать объект данных, где html-страница может получить доступ к тикетам, которые ей необходимы для рендеринга. Затем мы создаем метод getTickets. Он не принимает аргументов, но вызывает метод getOpen фабрики билетов, который возвращает открытые билеты. Мы также вызываем эту функцию в нашей функции инициализации, чтобы открытые билеты отображались на целевой странице при загрузке приложения.

Метод submitTicket принимает аргумент билета, содержащий данные, необходимые для создания нового билета в базе данных. Каждый новый билет создается со свойствами «archive: false» и «status: true». Затем мы отправляем полную заявку в функцию submitTicket фабрики билетов и перезагружаем страницу с новым содержимым.

Каждый из методов archiveTicket и deleteTicket принимает аргумент билета и отправляет этот билет в метод updateTicket и deleteTicket фабрики билетов соответственно. Затем мы перезагружаем маршрут, чтобы текущая страница обновлялась соответствующим образом. Наконец, мы назвали эту область «OpenController», которая связывает данные в open.html с OpenController.

Шаг 9 - Создайте представление и контроллер архивных заявок

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

Шаг 10 - Добавьте немного стиля

Стили необязательны. Вы можете ознакомиться с моей таблицей стилей здесь. Конечный продукт выглядит так: