Одностраничные приложения (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