Пошаговое руководство по JavaScript
Вступление
Это первая часть из трех статей, посвященных пониманию того, как работает архитектура MVC для создания интерфейсных приложений. Цель этой серии статей - понять, как структурировать интерфейсное приложение путем развития веб-страницы, на которой JavaScript используется в качестве языка сценариев, по направлению к приложению, в котором JavaScript используется как объектно-ориентированный язык.
В этом первом посте приложение будет создано с использованием VanillaJS. Поэтому в этой статье будет разработан самый большой объем кода, относящегося к DOM. Однако очень важно понимать, как все части приложения связаны и как оно структурировано.
Во второй части мы усилим код JavaScript, преобразовав его в версию TypeScript.
Наконец, в последней части мы трансформируем наш код, чтобы интегрировать его с фреймворком Angular.
Архитектура проекта
Нет ничего более ценного, чем изображение, чтобы понять, что мы собираемся построить. Ниже представлен GIF-файл, на котором показано приложение, которое мы собираемся создать.
Это приложение может быть создано с использованием одного файла JavaScript, который изменяет DOM документа и выполняет все операции, но это сильно связанный код, и мы не собираемся применять его в этой части.
Что такое архитектура MVC? MVC - это архитектура с тремя уровнями / частями:
- Модели - управляйте данными приложения. Модели будут анемичными (у них не будет функциональности), так как они будут отнесены к сервисам.
- Просмотры - визуальное представление моделей.
- Контроллеры - связи между службами и представлениями.
Ниже мы показываем файловую структуру, которая будет у нас в проблемной области:
Файл index.html
будет действовать как холст, на котором все приложение будет динамически построено с использованием элемента root
. Кроме того, этот файл будет действовать как загрузчик всех файлов, поскольку они будут связаны в самом файле html.
Наконец, наша файловая архитектура состоит из следующих файлов JavaScript:
- user.model.js - атрибуты (модель) пользователя.
- user.controller.js - тот, кто отвечает за присоединение к службе и представление.
- user.service.js - управление всеми операциями с пользователями.
- user.views.js - отвечает за обновление и изменение экрана дисплея.
HTML-файл показан ниже:
Модели (анемичные)
Первым классом, созданным в этом примере, является модель приложения user.model.js
, которая состоит из атрибутов класса и частного метода, который генерирует случайные идентификаторы (эти идентификаторы могут поступать из базы данных на сервере).
У моделей будут следующие поля:
- id - уникальное значение
- name - имена пользователей.
- age - возраст пользователей.
- complete - логическое значение, которое позволяет узнать, можем ли мы вычеркнуть пользователя из списка.
user.model.js
показан ниже:
Операции, выполняемые над пользователями, выполняются в сервисе. Сервис - это то, что позволяет моделям быть анемичными, поскольку вся логическая нагрузка находится в них. В этом конкретном случае мы будем использовать массив для хранения всех пользователей и создать четыре метода, связанных с чтением, изменением, созданием и удалением (CRUD) пользователей. Следует отметить, что служба использует модель, создавая экземпляры объектов, извлеченных из LocalStorage
в User class
. Это потому, что LocalStorage
хранит только данные, а не прототипы сохраненных данных. То же самое происходит с данными, которые передаются от серверной части к клиентской: для них не созданы экземпляры классов.
Конструктор нашего класса выглядит следующим образом:
Обратите внимание, что мы определили переменную класса с именем users
, в которой хранятся все пользователи после того, как они были преобразованы из плоского объекта в прототипный объект класса User
.
Следующее, что мы должны определить в сервисе, - это каждая операция, которую мы хотим разработать. Эти операции показаны ниже с использованием ECMAScript, без использования единственной строки в TypeScript:
Остается определить метод commit
, который отвечает за сохранение операции, выполняемой в нашем хранилище данных (в нашем случае LocalStorage
).
Этот метод вызывает функцию callback
, которая была привязана при создании службы, как можно увидеть в определении метода bindUserListChanged
. Я уже могу сказать вам, что этот обратный вызов - это функция, которая поступает из представления и отвечает за обновление списка пользователей на экране.
Файл user.service.js
выглядит следующим образом:
Вид - это визуальное представление модели. Вместо того, чтобы создавать HTML-контент и внедрять его (как это делается во многих фреймворках), мы решили динамически создавать все представление. Первое, что нужно сделать, это кэшировать все переменные представления с помощью методов DOM, как показано в конструкторе представления:
Следующая наиболее важная точка зрения - это объединение представления с методами службы (которые будут отправлены через контроллер). Например, метод bindAddUser
получает функцию драйвера в качестве параметра, который будет выполнять операцию addUser
, описанную в службе. В bindXXX
методах определяется EventListener
каждого из элементов управления представлением. Обратите внимание, что из представления у нас есть доступ ко всем данным, предоставленным пользователем с экрана, который подключен через handler
функции.
Остальной код представления обрабатывает DOM документа. Файл user.view.js
выглядит следующим образом:
Последний файл этой архитектуры - это контроллер. Контроллер получает две зависимости, которые у него есть (сервис и представление), путем внедрения зависимостей (DI). Эти зависимости хранятся в контроллере в частных переменных. Кроме того, конструктор устанавливает явное соединение между представлением и службами, поскольку контроллер - единственный элемент, имеющий доступ к обеим сторонам.
Файл user.controller.js
показан ниже:
Последний пункт нашего приложения - это средство запуска приложений. В нашем случае мы назвали это app.js
. Приложение выполняется путем создания различных элементов: UserService
, UserView
и UserController
, как показано в файле app.js
.
Заключение
В этом первом посте мы разработали веб-приложение, в котором проект был структурирован в соответствии с архитектурой MVC, в которой используются анемичные модели, а ответственность за логику лежит на сервисах.
Очень важно подчеркнуть, что цель обучения этой части - понять структурирование проекта в разных файлах с разными обязанностями и то, как представление полностью не зависит от модели / службы и контроллера.
В следующей части мы укрепим JavaScript с помощью TypeScript, который даст нам более мощный язык для разработки веб-приложений. Тот факт, что мы использовали JavaScript, заставил нас написать много подробного и повторяющегося кода для управления DOM (это будет минимизировано с помощью фреймворка Angular).
Ветвь GitHub этого сообщения - https://github.com/Caballerog/VanillaJS-MVC-Users.