Одностраничные приложения (SPA) широко распространены в современной разработке веб-приложений. Преимущество SPA в том, что страница не требует перезагрузки. Это позволяет пользователю взаимодействовать с приложением практически без простоев. При правильной реализации в браузере всегда будет отображаться контент, даже если пользователь щелкнет ссылку на странице. Будет обработана только часть страницы, что обеспечит бесперебойное взаимодействие с пользователем с минимальным временем ожидания.
В рамках учебной программы Flatiron School я создал SPA, используя бэкэнд-API Rails в сочетании с ванильным интерфейсом Javascript. Во внешнем интерфейсе используется объектная ориентация JS (ОО) для удобной и структурированной организации кода. Приложение, которое я создал, называется «Gastropoda» и представляет собой простой литературный журнал, предназначенный для сосредоточения внимания на содержании рассказов.
Основная проблема, с которой я столкнулся при создании этого, была связана с контекстом, для которого я кодировал. Поскольку я впервые работал с объектно-ориентированным JS, я знал только ключевое слово this
. Я знаком с «я» в Ruby, и хотя this
похоже на «я», оно достаточно отличается, что затрудняет избегание ошибок JS.
Я по умолчанию использовал this
в начале сборки. Как только в консоли появились ошибки, я внес изменение, создав переменную в верхней части метода и назначив ее this
, например const self = this
. Хотя это работает, в каждом методе, в котором я это делал, это оказалось ненужным. Я решил заменить все эти ненужные переменные, реализовав стрелочные функции вместо классических объявлений функций.
Прелесть стрелочных функций (если ваши потребности совпадают с моими) заключается в том, что они не связывают свои собственные this
, а просто наследуются из области видимости родителя. Поэтому, если вам не нужен доступ к содержимому, для которого вы это вызываете, могут быть полезны стрелочные функции.
Другая реализация, которую я использовал для управления контекстом функций, — использование bind
. В приведенном ниже методе устанавливаются прослушиватели событий, а функции обратного вызова передаются в качестве аргументов. Поскольку передаваемые функции обратного вызова также являются методами внутри этого класса, контекст этих функций будет любым, предшествующим .addEventListener
. Чтобы решить эту проблему, я привязываю this
к функции обратного вызова, чтобы назначить контекст.
Еще одна проблема, которая некоторое время вызывала у меня затруднения, заключалась в том, как передать аргумент функции обратного вызова, когда вы используете .bind
. Последние две строки метода ниже показывают, что аргумент находится в круглых скобках .bind
, но идет после первого аргумента this
.
Я также потратил значительное количество времени, избегая новых запросов на выборку, если это не было абсолютно необходимо. При первоначальном запуске приложения вызывается метод класса Entry.loadEntries()
. В этом классе живет большая часть кода JS. Этот класс имеет статический метод с именем allEntries
, который изначально указывает на пустой массив. Этот массив заполняется входными объектами при вызове loadEntries()
, который помещает эти новые объекты в allEntries
как часть конструктора для экземпляров Entry
. Таким образом, с самого начала инициализируется запрос на выборку get
к серверной части, и это единственный раз, когда используется запрос на получение записей. Я настроил данные с помощью сериализатора, чтобы все, что возвращал запрос на выборку, было всеми данными, которые мне нужны для приложения. Сюда входят объекты комментариев, связанные с записью (у записи много комментариев, и комментарий принадлежит записи). Из-за этого запрос на выборку для отдельной записи не нужен, поскольку все данные превращаются в объекты Javascript и хранятся в доступном массиве.
Финальное СПА
Репозиторий Github для этого приложения можно найти по ссылке ниже. Не стесняйтесь клонировать репозиторий и запускать приложение в браузере, чтобы поиграть с ним. Любые комментарии или вопросы приветствуются!
https://github.com/dougschallmoser/gastropoda-js-app