Пошаговое руководство по 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.