одностраничное веб приложение пример

Как создать SPA на JS и PHP за час

Одностраничные приложения уже давно не в новинку, а скоро вообще станут стандартом веб-разработки. Узнайте, как их создавать, — пока не поздно.

одностраничное веб приложение пример. b47aae052eb771f43c5517bb6e8ea60e. одностраничное веб приложение пример фото. одностраничное веб приложение пример-b47aae052eb771f43c5517bb6e8ea60e. картинка одностраничное веб приложение пример. картинка b47aae052eb771f43c5517bb6e8ea60e.

одностраничное веб приложение пример. ba7d9f49771960a890c9cdf14b6abd85. одностраничное веб приложение пример фото. одностраничное веб приложение пример-ba7d9f49771960a890c9cdf14b6abd85. картинка одностраничное веб приложение пример. картинка ba7d9f49771960a890c9cdf14b6abd85.

SPA (англ. Single Page Application — одностраничное приложение) — это сайт, для работы которого не требуется обновление страницы, потому что все данные загружаются с помощью скриптов.

Принцип работы SPA прост: когда вы совершаете какое-то действие, например нажимаете на ссылку, скрипт перехватывает это событие. Он отменяет действие по умолчанию и вместо этого сам обменивается данными с сервером, а потом выводит их на странице.

Обычно такой сайт быстрее загружается, потому что ему нужно скачать только определённые данные, а не всю страницу. Также часть контента может быть закеширована, то есть загружена заранее. В этом случае обновление может произойти мгновенно.

SPA отлично подходит для интернет-магазинов: пользователь может нажать на кнопку «Добавить в корзину» и тут же продолжить смотреть другие товары. Но и для обычных блогов такая технология вполне уместна.

Создать что-то подобное можно и за час. Вы можете посмотреть репозиторий с полным кодом приложения.

одностраничное веб приложение пример. kucheryaviy. одностраничное веб приложение пример фото. одностраничное веб приложение пример-kucheryaviy. картинка одностраничное веб приложение пример. картинка kucheryaviy.

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

Каким должно быть SPA

Чтобы SPA было удобно пользоваться, нужно правильно выстроить обмен данными с сервером. Вот несколько рекомендаций.

Это небольшой список, но он очень важен, потому что иначе ваше SPA станет менее удобным, чем обычный сайт.

Источник

Single Page Application: как работает сайт-приложение

Это не сайт и не приложение. Что это?

Эта статья для тех, кому интересны технологии веба и кто хочет работать в серьёзной веб-разработке.

Обычный сайт состоит из множества HTML-страниц. Вы кликаете по ссылкам, браузер загружает новые страницы по этим ссылкам, у вас появляется ощущение движения от одной страницы к другой. Страницы могут лежать как файлы на каком-то сервере или генерироваться под ваш запрос какой-то серверной программой. Но, условно говоря, каждый «экран» сайта — это отдельная техническая сущность, отдельный документ. И мы между ними перемещаемся.

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

В начале 2010-х появилась новая концепция — нечто среднее между сайтом и приложением. Такую архитектуру называют SPA — Single Page Application. Если вы пользовались VK.com или Facebook.com, вы уже сталкивались с такими продуктами.

Коротко главное

SPA работает так: когда пользователь открывает страницу, браузер загружает сразу весь код приложения. Но показывает только конкретный модуль — часть сайта, которая нужна пользователю. Когда пользователь переходит в другую часть приложения, браузер берёт уже загруженные данные и показывает ему. И, если нужно, динамически подгружает с сервера нужный контент без обновления страницы.

С одной стороны, такие приложения работают быстро и меньше нагружают сервер. С другой стороны, они требуют большей загрузки на старте.

Объясним на квадратах

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

одностраничное веб приложение пример. image5 3. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image5 3. картинка одностраничное веб приложение пример. картинка image5 3.

На первый взгляд, разницы между сайтом и приложением нет. Чтобы её заметить, нажмём на кнопку с другим цветом.

одностраничное веб приложение пример. image1 2. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image1 2. картинка одностраничное веб приложение пример. картинка image1 2.

Здесь становится заметно, что сайт и одностраничное приложение ведут себя по-разному:

одностраничное веб приложение пример. image6 1. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image6 1. картинка одностраничное веб приложение пример. картинка image6 1. одностраничное веб приложение пример. image3 1. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image3 1. картинка одностраничное веб приложение пример. картинка image3 1. одностраничное веб приложение пример. image4 3. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image4 3. картинка одностраничное веб приложение пример. картинка image4 3. одностраничное веб приложение пример. image2 2. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image2 2. картинка одностраничное веб приложение пример. картинка image2 2.

Страница сайта обновится целиком. Получается, мы говорим серверу: «Привет, сделай-ка квадраты зелёными». Он говорит: «Хорошо. Но ещё вот вам снова шапка сайта и подвал, а также кнопки и метаданные». И отдаёт целиком новый HTML-файл.

В одностраничном приложении обновится только цвет квадратов. Браузер отправляет серверу запрос, тот возвращает нужный параметр, квадраты красятся, всё остальное остаётся неизменным.

Теперь представьте, что у вас не простые квадраты, а интернет-магазин. Пользователь переходит с одного товара на другой, но страница при этом не перезагружается, а динамически подтягивает фото, название, описание и цену. Так и работают SPA.

Зачем нужны SPA

Одностраничные приложения чаще всего используют в сервисах, где пользователь проводит на одной странице много времени или совершает с ней какие-то действия, например:

Веб-версии Gmail, Facebook Netflix, AirBnB и Pinterest — одностраничные приложения. Технология настолько распространена, что её используют даже для сайтов компаний. Посмотрите, например, на страницу Digital Agency London. Из русскоязычных проектов — Meduza.

SPA может обмениваться данными с сервером без перезагрузки страницы, с помощью ajax-запросов. Благодаря этому наполнение страницы может меняться динамически. Например, раньше в социальной сети нужно было перезагрузить страницу, чтобы проверить, нет ли новых сообщений, теперь они появляются автоматически.

Обратите внимание, например, как работает переключение между разделами в интерфейсе Фейсбука: если открыть главную, а потом перейти в «Группы», то содержание страницы изменится, но шапка останется на своём месте — перезагрузки страницы не происходит.

Преимущества SPA

SPA быстрые. Переход между модулями в приложении происходит быстрее: нужные ресурсы уже загружены, нужно просто подставить данные, которые запросил пользователь. Часто при этом сервер возвращает не тяжеловесный HTML, а лёгкий JSON или XML.

Ещё использование JSON упрощает разработку приложения для разных платформ. Если для веб-версии разработать обычный сайт, который принимает от сервера HTML, то для мобильного приложения придётся писать доработку, так как там HTML не подойдёт. JSON делает ответ сервера универсальным.

SPA гибкие. Раз пользователь всё время работает с одной страницей, проще делать интересные переходы и анимацию элементов. Можно работать с состоянием кнопок, вкладок и переключателей. Таким образом, интерфейс SPA может быть похож скорее на полноценное приложение, а не на простой сайт.

SPA работают везде. Всё, что нужно для SPA — поддержка JavaScript. Такие сайты хорошо работают и на десктопе, и в вебе, могут отчасти заменить полноценные мобильные приложения.

Недостатки SPA

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

Похожая проблема с некоторыми системами аналитики. Вот что про SPA говорит Google-аналитика: «Стандартный тег Google Аналитики хорошо подходит для обычных сайтов, поскольку его код выполняется при каждой загрузке новой страницы. Однако при работе с одностраничным приложением такой код будет выполнен лишь один раз». То есть чтобы корректно собирать аналитику, придётся самостоятельно настроить отслеживание нужных событий.

Зависимость от интернета. Для запуска веб-приложения нужна связь с сервером, так что в большинстве случаев без интернета не обойтись, как и с обычными сайтами. Этим SPA проигрывают обычным приложениям.

Хотя здесь есть исключение — если во время первой загрузки браузер получает все данные и больше ничего подгружать не нужно, то можно работать и без интернета.

SPA не для новичков. Написать такое приложение на простом HTML и CSS не получится, нужно знать JS. Часто для этого используют фреймворки — React, Angular, Vue, Ember и другие. В любом случая для проекта нужны более компетентные разработчики.

Этот материал мы подготовили по мотивам интервью с Александром Штыковым — руководителем фронтенд-команд в Деловой Среде. У Деловой Среды есть образовательная платформа, которая работает как SPA.

Что дальше?

Если хотите сделать своё веб-приложение, посмотрите инструкцию, как запустить приложение на React и репозиторий на GitHub.Чтобы разрабатывать SPA, не помещает хорошо разбираться в JS, его фреймворках и других веб-технологиях. На Практикуме есть курс «Как стать веб-разработчиком» и «Как стать мидл фронтенд-разработчиком».

Источник

Как написать одностраничное приложение (SPA) с использованием Vue.js

одностраничное веб приложение пример. image loader. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image loader. картинка одностраничное веб приложение пример. картинка image loader.

Одностраничные приложения (SPA) имеют мнжество преимуществ, таких как скорость, по-настоящему хороший UX, и полный контроль HTML-разметки. Становится всё больше и больше сайтов SPA; всё больше инструментов, которые упрощают процесс разработки SPA. Вы, вероятно уже читали о молодом и перспективном фреймворке Vue.js. Предлагаю вам глубже погрузиться в Vue и на конкретном примере разобраться с простым SPA.

Мы напишем клиент-серверное приложение простейшего блога. Приложение будет отображать список записей а также полный текст каждой отдельной записи. И само собой, всё это будет происходить без перезагрузки страницы.

Ознакомившись с примером этого приложения, вы научитесь извлекать данные в Vue, создавать роуты и разберётесь с интересной особенностью Vue — однофайловыми компонентами.

Бэкенд

В этом руководстве мы в основном сосредоточимся на фронтенде на Vue. Размышлять о написании REST бэкенда мы не будем. Для примера будет использоваться сервис jsonplaceholder.typicode.com предостовляющий заглушку в виде REST API.

Фронтенд

Инструменты

Начать работу с Vue очень просто. С использованием правильных инструментов это ещё проще. Рекомендую взглянуть на проект vue-awesome, который содержит список инструментов, компонентов, библиотек и плагинов на все случаи жизни.

Vue-cli

При создании нового проекта рекомендуется воспользоваться Vue-cli. Так можно создавать проекты с использованием официальных шаблонных проектов Vue, или одного из множества шаблонных проектов с открытым исходным кодом, и, конечно же, вы можете создать свой собственный и использовать его в любом месте.

Итак, для начала установим vue-cli в качестве глобального пакета:

Затем проинициализируем проект с выбранным шаблоном; для нашего примера более чем достаточно использовать webpack-simple.

Далее перейдём в папку vue-spa и запустим npm install в терминале. После установки всех пакетов, мы можем запустить наше приложение в режиме разработки.

Эта команда автоматически запустит наш проект на локальном dev-сервере webpack. В браузере появится наше простейшее приложение Vue. Конечно оно выглядит совсем не так, как бы нам хотелось, и годится лишь в качестве отправной точки для начала чего-то большего. Чтобы продолжить работу, предлагаю сначала ознакомиться со структурой нашего шаблона.

Шаблон webpack-simple

Внутри шаблон webpack-simple имеет следующую структуру:

одностраничное веб приложение пример. image loader. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image loader. картинка одностраничное веб приложение пример. картинка image loader.

Файл index.html содержит простую разметку HTML с единственным элементом “app” в body. Он будет заменён на DOM, сгенерированный vue. По этой причине тэг body не рекомендуется использовать в качестве корневого элемента.

Однофайловые компоненты

одностраничное веб приложение пример. image loader. одностраничное веб приложение пример фото. одностраничное веб приложение пример-image loader. картинка одностраничное веб приложение пример. картинка image loader.

Кроме того, можно добавить немного стилей, чтобы приложение выглядело лучше.
Код приложения хостится на github.com. Достаточно клонировать репозиторий и переключать ветку по номеру шага чтобы проследить разработку приложения шаг за шагом например:

В настоящий момент нам абсолютно нечего отображать в нашей навигационной панели, поэтому давайте получим данные с сервера. Для этого я выбрал Axios — простой в использовании HTTP-клиент. Вы также можете использовать любой удобный для вас способ, например, Vue-ресурс или собственную выборку или даже jQuery Ajax.

Шаг 2

Затем импортируем его в компонент App и определим метод getAllPosts() который будет делать запрос к серверу и присваивать его свойству posts. Вызываем метод в хуке created(), который будет вызываться после создания экземпляра Vue и после установки настроек обращения к данным.

А теперь отобразим все заголовки записей в боковой панели.

До сих пор мы отображали только заголовки записей, но пока мы ещё не можем видеть сами записи. Теперь необходимо отобразить полный пост в разделе контента в соответствии с выбранным названием на боковой панели. В то же время хотелось бы, чтобы каждая запись была доступна по своему уникальному адресу.

Шаг 3

Для этого воспользуемся официальной Vue библиотекой vue-router. Как уже понятно из названия, библиотека позволяет настраивать роутинг для нашего приложения.
Установим библиотеку:

Для настройки роутинга вернёмся к файлу main.js. Здесь мы определим настройки роутинга и добавим их в наш экземпляр Vue.

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

Остался заключительный шаг. Нам нужно отобразить содержимое записи поста.

Шаг 4

Перейдём к файлу Post.vue, в котором добавим простой шаблон:

Затем нам нужно установить параметры экземпляра Vue для этого компонента. Здесь все также как в настройках отображения всех постов. Объявим опцию props с меняющимся id, которая будет получать номер нашего поста. Далее, объявим объект данных, как уже делали в App.vue:

Затем опишем метод getPost(), который будет получать только одну запись поста по идентификатору и вызовем его в хуке created().

Почти готово. Если мы запустим приложение сейчас, мы увидим, что, хотя URL-адрес меняется, мы видим единственный пост, который был отрисован первым. Дело в том, что для отрисовки разных постов у нас есть один и тот же компонент, и Vue не нужно его пересоздавать из-за лишней траты ресурсов, а это также означает, что хуки жизненного цикла компонента не будут вызваны.
Чтобы это исправить, нам просто нужно установить watcher для объекта $route.

Теперь всё работает так, как и должно. Чтобы получить версию для продакшина достаточно выполнить команду npm run build в консоли.

Источник

Одностраничные (spa) и многостраничные (pwa) веб-приложения

Чем отличаются веб-приложения MPA, SPA и PWA, для каких задач подходят. Разбор преимуществ, недостатков и отличий методов разработки.

Существует три основных подхода к разработке веб-приложений: одностраничные (SPA), многостраничные (MPA) и прогрессивные (PWA). Они выделяются среди других подходов простотой разработки, удобством для пользователей и широкими возможностями для развития бизнеса.

Рассказываем, чем отличаются компоненты MPA, SPA и PWA, какие у них преимущества и недостатки, что из них выбрать и для каких задач.

SPA или Single Page Application — это одностраничное веб-приложение, которое загружается на одну HTML-страницу. Благодаря динамическому обновлению с помощью JavaScript, во время использования не нужно перезагружать или подгружать дополнительные страницы. На практике это означает, что пользователь видит в браузере весь основной контент, а при прокрутке или переходах на другие страницы, вместо полной перезагрузки нужные элементы просто подгружаются.

В процессе работы пользователю может показаться, что он запустил не веб-сайт, а десктопное приложение, так как оно мгновенно реагирует на все его действия, без задержек и «подвисаний».

Такого эффекта удается добиться с помощью продвинутых фреймворков JavaScript: Angular, React, Ember, Meteor, Knockout.

Примеры динамических приложений: Gmail, Google Maps, Facebok, GitHub, Meduza.

MPA или Multi Page Application — это многостраничные приложения, которые работают по традиционной схеме. Это означает, что при каждом незначительном изменении данных или загрузке новой информации страница обновляется. Такие приложения тяжелее, чем одностраничные, поэтому их использование целесообразно только в тех случаях, когда нужно отобразить большое количество контента.

Тесная связь между бекендом и фронтендом, поэтому их не получается развивать параллельно;сложная разработка — требуют использования фреймворков как на стороне клиента, так и на стороне сервера, что увеличивает сроки и бюджет разработки.

При выборе типа веб-приложения нужно ориентироваться на то, зачем именно вы его создаете. Многостраничный сайт подойдет интернет-магазину с большим количеством товаров и услуг, а если у вас, к примеру, инфобизнес, где можно изложить всю информацию в рамках сжатого веб-пространства — подойдет одностраничный сайт.

Прогрессивные приложения или Progressive Web Application взаимодействуют с пользователем, как приложение. Они могут устанавливаться на главный экран смартфона, отправлять push-уведомления и работать в офлайн-режиме.

Пример: Google Docs.

Не все браузеры поддерживают основные функции таких приложений (например, Firefox и Edge).

SPA и PWA — это веб-сайты, которые постепенно смещают со своих позиций классические MPA. Так происходит из-за того, что они более простые в разработке, быстрее работают и нравятся пользователям. Однако у них есть слабое место — SEO-оптимизация. Пока еще не все браузеры могут с ними нормально работать, поэтому, чтобы сделать такие приложения дружественными для сео, нужно прибегать к ряду ухищрений. MPA-сайты в этом плане более простые и надежные.

А если же использовать SPA + SSR, то MPA приложения проигрывают по производительности практически во всех аспектах.

Так же, с помощью SSR мы можем реализовывать следующую технику: загружать только те части js / css, которые необходимы для работы конкретного компонента, т.е. представьте, что у нас есть страница каталога с закрытой картой и с закрытыми фильтрами. Когда мы загружаем эту страницу, то у нас не подгружаются компоненты, связанные с картой и фильтрами (т.к. она закрыты) => размер страницы будет крайне мал, а когда человек включает карту или (и) фильтры, то у нас динамически со стороны сервера подгружаются эти самые компоненты (Code Splitting), крч мы подгружаем компоненты только тогда, когда в них есть необходимость.
И дополню, что Code Splitting работает не только для отдельных компонентов, но и для целых страниц, что очень сильно облегчает размер бандла => скорость отдачи web-приложения на сторону клиента.

3) Утечка памяти: если над SPA приложением работает (ют) квалифицированные разработчики, то я на 99.8% уверен в том, что подобной проблемы не возникнет, т.к. методы / тулзы для профилирования (анализа работы приложения) уже давным-давно вышли на новый уровень и сейчас не эпоха ie6, где люди дебажили (искали баги / ошибки) с помощью alert’s. И непонятно, почему этот пункт отнесся именно к SPA, ведь в любом приложении, где есть хоть какая-то логика, может возникнуть подобная ситуация, ни?

5) Про PWA / TWA даже писать не буду, т.к. для этого нужно писать отдельную статью о том, что в этой статье не так.

Для frontend developer’ов: я постарался выражаться не с точки зрения программиста, а с точки зрения «обывателя», чтобы всем было понятно, о чем я говорю, поэтому примите и простите.

Источник

Одностраничные приложения: создание современных адаптивных веб-приложений с помощью ASP.NET

Продукты и технологии:

Single-Page Applications (SPA), ASP.NET Web API, Knockout.js, Ember.js, AJAX и HTML5

В статье рассматриваются:

Одностраничные приложения (Single-Page Applications, SPA) — это веб-приложения, которые загружают одну HTML-страницу и динамически обновляют ее при взаимодействии с пользователем.

SPA используют AJAX и HTML5 для создания гибких и адаптивных веб-приложений без постоянных перезагрузок страницы. Однако это означает, что большая часть работы возлагается на клиентскую сторону, а именно на JavaScript-код. Разработчику для традиционной ASP.NET может быть трудно совершить такой кульбит. К счастью, существует множество JavaScript-инфраструктур с открытым исходным кодом, которые облегчают создание SPA.

В этой статье я пошагово пройду процесс создания простого SPA-приложения. Попутно вы ознакомитесь с некоторыми фундаментальными концепциями создания SPA, в том числе с шаблонами Model-View-Controller (MVC) и Model-View-ViewModel (MVVM), связыванием с данными и маршрутизацией (routing).

О приложении-примере

Я создал приложение-пример для операций с простой базой данных по фильмам (рис. 1). В крайнем слева столбце страницы отображается список жанров. Выбор жанра приводит к появлению списка соответствующих фильмов. Кнопка Edit рядом с записью позволяет изменять эту запись. После редактирования можно щелкнуть кнопку Save для передачи обновления на сервер или кнопку Cancel для отмены изменений.

одностраничное веб приложение пример. dn463786.wassonspa1113 figure 1 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wassonspa1113 figure 1 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wassonspa1113 figure 1 hires(ru ru,msdn.10).
Рис. 1. SPA-приложение для базы данных по фильмам

Я создал две версии этого приложения: одна из них использует библиотеку Knockout.js, а другая — библиотеку Ember.js. Эти две библиотеки основаны на разных подходах, поэтому будет весьма поучительно сравнить их. В обоих случаях клиентское приложение не требовало более 150 строк JavaScript-кода. На серверной стороне я задействовал ASP.NET Web API, чтобы обслуживать JSON для клиента. Исходный код обеих версий вы найдете на github.com/MikeWasson/MoviesSPA.

(Примечание Я создавал приложение, используя RC-версию Visual Studio 2013. В RTM-версии некоторые вещи могли измениться, но они не должны повлиять на код.)

Обзор

В традиционном веб-приложении при каждом вызове сервера тот осуществляет рендеринг новой HTML-страницы. Это вызывает обновление страницы в браузере. Если вы когда-нибудь писали приложение Web Forms или PHP, этот жизненный цикл страниц должен быть знаком вам.

В SPA после загрузки первой страницы все взаимодействие с сервером происходит через AJAX-вызовы. Эти AJAX-вызовы возвращают данные (не разметку) — обычно в формате JSON. Приложение использует JSON-данные для динамического обновления страницы без ее перезагрузки. Рис. 2 иллюстрирует разницу между этими двумя подходами.

одностраничное веб приложение пример. dn463786.wasson figure2 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wasson figure2 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wasson figure2 hires(ru ru,msdn.10).
Рис. 2. Сравнение традиционного жизненного цикла страницы с жизненным циклом в SPA

Traditional Page LifecycleТрадиционный жизненный цикл страницы
ClientКлиент
Page ReloadПерезагрузка страницы
ServerСервер
Initial RequestНачальный запрос
HTMLHTML
Form POSTПередача формы командой POST
SPA LifecycleЖизненный цикл в SPA
AJAXAJAX
JSONJSON

Одно из преимуществ SPA очевидно: приложения более гибкие и адаптивные, свободные от рваного эффекта перезагрузки страницы и ее рендеринга заново. Другое преимущество может оказаться менее очевидным и касается того, как вы проектируете архитектуру веб-приложения. Отправка данных приложения как JSON обеспечивает разделение между презентационной частью (HTML-разметкой) и прикладной логикой (AJAX-запросы плюс JSON-ответы).

Это разделение упрощает проектирование и развитие каждого уровня. В SPA-приложении с тщательно продуманной архитектурой можно изменять HTML-разметку, не касаясь кода, который реализует прикладную логику (по крайней мере, в идеале). Вы увидите это на практике, когда мы будем обсуждать связывание с данными.

В чистом SPA все UI-взаимодействие происходит на клиентской стороне через JavaScript и CSS. После начальной загрузки страницы сервер действует исключительно как уровень сервисов. Клиенту нужно просто знать, какие HTTP-запросы он должен посылать. Ему не важно, как сервер реализует свою часть.

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

Создание проекта в Visual Studio

В Visual Studio 2013 есть один тип проекта ASP.NET Web Application. Мастер этого проекта позволяет выбрать ASP.NET-компоненты, которые будут включены в проект. Я начал с шаблона Empty, а затем добавил в проект ASP.NET Web API, установив флажок Web API в разделе Add folders and core references for, как показано на рис. 3.

одностраничное веб приложение пример. dn463786.wassonspa1113 figure 3 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wassonspa1113 figure 3 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wassonspa1113 figure 3 hires(ru ru,msdn.10).
Рис. 3. Создание нового ASP.NET-проекта в Visual Studio 2013

В новом проекте есть все библиотеки, необходимые для Web API, а также кое-какой конфигурационный код Web API. Я не вводил никаких зависимостей от Web Forms или ASP.NET MVC.

Обратите внимание на рис. 3, что Visual Studio 2013 включает шаблон Single Page Application. Этот шаблон устанавливает скелет SPA-приложения, основанный на Knockout.js. Он поддерживает вход с применением базы данных с информацией о членстве в группах или с помощью внешнего провайдера аутентификации. Я не стал использовать этот шаблон в своем приложении, потому что хотел показать более простой пример с нуля. Шаблон SPA — отличный ресурс, особенно если вам нужно добавить аутентификацию в приложение.

Создание уровня сервисов

Я использовал ASP.NET Web API, чтобы создать простой REST API для приложения. Не буду здесь вдаваться в детали Web API — подробности вы можете прочитать по ссылке asp.net/web-api.

Сначала я создал класс Movie, представляющий фильм. Этот класс делает две вещи:

Вы не обязаны использовать одну модель для обеих целей. Например, вам может понадобиться, чтобы схема базы данных отличалась от полезных данных JSON. В этом приложении я ничего не усложняю:

Затем я воспользовался технологией scaffolding в Visual Studio для создания контроллера Web API, который задействует EF в качестве уровня данных. Чтобы применить эту технологию, щелкните правой кнопкой мыши папку Controllers в Solution Explorer и выберите Add | New Scaffolded Item. В мастере Add Scaffold укажите Web API 2 Controller with actions, using Entity Framework, как показано на рис. 4.

одностраничное веб приложение пример. dn463786.wassonspa1113 figure 4 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wassonspa1113 figure 4 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wassonspa1113 figure 4 hires(ru ru,msdn.10).
Рис. 4. Добавление контроллера Web API

На рис. 5 приведен мастер Add Controller. Я присвоил контроллеру имя MoviesController. Имя имеет значение, так как URI для REST API основываются на имени контроллера. Я также установил флажок Use async controller actions, чтобы задействовать преимущества новой функциональности async в EF 6. Я выбрал класс Movie в качестве модели и указал New data context, чтобы создать новый контекст данных EF.

одностраничное веб приложение пример. dn463786.wassonspa1113 figure 5 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wassonspa1113 figure 5 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wassonspa1113 figure 5 hires(ru ru,msdn.10).
Рис. 5. Мастер Add Controller

Мастер добавляет два файла:

В табл. 1 показан REST API по умолчанию, создаваемый технологией scaffolding.

Табл. 1. REST API по умолчанию, созданный технологией scaffolding из Web API

HTTP-командаURIОписание
GET/api/moviesПолучить список всех фильмов
GET/api/movies/

Получить фильм с идентификатором, равным
PUT/api/movies/

Обновить фильм с идентификатором, равным
POST/api/moviesДобавить новый фильм в базу данных
DELETE/api/movies/

Удалить фильм из базы данных

Значения в фигурных скобках являются заменителями для подстановки. Например, чтобы получить фильм с идентификатором, равным 5, URI должен выглядеть так: /api/movies/5.

Я расширил этот API, добавив метод, который находит все фильмы указанного жанра:

Клиент указывает жанр в строке запроса URI. Например, чтобы получить все фильмы жанра Drama, клиент посылает GET-запрос на /api/movies?genre=drama. Web API автоматически связывает параметр запроса с параметром genre в методе GetMoviesByGenre.

Создание веб-клиента

До сих пор я просто создавал REST API. Если вы отправите GET-запрос на /api/movies?genre=drama, исходный HTTP-ответ будет выглядеть так:

Теперь мне нужно написать клиентское приложение, которое делает с этим что-то осмысленное. Базовый рабочий процесс такой:

Вы могли закодировать все это вручную. Например, вот некоторый jQuery-код, который создает список названий фильмов:

В этом коде есть кое-какие проблемы. Он смешивает прикладную логику с презентационной и тесно связан с вашим HTML. Кроме того, писать его весьма утомительно. Вместо того чтобы сосредоточиться на приложении, вы тратите время на написание обработчиков событий и кода, манипулирующего DOM.

Решение заключается в том, чтобы использовать JavaScript-инфраструктуру. К счастью, их выбор довольно велик, и эти инфраструктуры имеют открытый исходный код. К некоторым из более популярных инфраструктур относятся Backbone, Angular, Ember, Knockout, Dojo и JavaScriptMVC. Большинство использует вариации шаблонов MVC или MVVM, поэтому будет полезно вкратце рассмотреть эти шаблоны.

Шаблоны MVC и MVVM

Корни шаблона MVC уходят в 80-е годы прошлого века и связаны с ранними графическими UI. Цель MVC — разбиение кода на три уровня со своими обязанностями (рис. 6). Вот что они делают:

одностраничное веб приложение пример. dn463786.wasson figure7 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wasson figure7 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wasson figure7 hires(ru ru,msdn.10).

Рис. 6. Шаблон MVC

ViewView
ControllerController
ModelModel
User InputПользовательский ввод
UpdatesОбновления
ModifiesМодифицирует

Более современная вариация MVC — шаблон MVVM (рис. 7). В шаблоне MVVM:

одностраничное веб приложение пример. dn463786.wasson figure8 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wasson figure8 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wasson figure8 hires(ru ru,msdn.10).

Рис. 7. Шаблон MVVM

View ModelView Model

В JavaScript-инфраструктуре MVVM представлением является разметка, а моделью представления — код.

MVC имеет много вариаций, а литература по MVC зачастую противоречива и запутана. По-видимому, это и не удивительно для проектировочного шаблона, который начал свою жизнь со Smalltalk-76 и все еще применяется в современных веб-приложениях. Поэтому, хоть и хорошо знать теорию, главное — понимать конкретную инфраструктуру MVC, используемую вами.

Создание веб-клиента с применением Knockout.js

Для первой версии своего приложения я использовал библиотеку Knockout.js. Knockout следует шаблону MVVM, соединяя представление и модель представления через связывание с данными.

Чтобы создать привязки данных, вы добавляете к HTML-элементам специальный атрибут data-binding. Например, следующая разметка связывает элемент span со свойством genre в модели представления. Всякий раз, когда изменяется значение genre, Knockout автоматически обновляет HTML:

Привязки также могут работать в другом направлении, скажем, если пользователь вводит текст в поле, Knockout обновляет соответствующее свойство в модели представления.

Удобно, что связывание с данными осуществляется декларативно. Вам не требуется подключать модель представления к элементам HTML-страницы. Просто добавьте атрибут data-binding, и Knockout сделает остальное.

Я начал с создания HTML-страницы с базовой разметкой без связывания с данными, как показано на рис. 8.

Рис. 8. Начальная HTML-разметка

(Примечание Я использовал библиотеку Bootstrap для оформления внешнего вида приложения, поэтому в настоящем приложении уйма дополнительных элементов

Создание модели представления

Наблюдаемые объекты (observables) занимают центральное место в системе связывания с данными в Knockout. Наблюдаемым является объект, который хранит какое-то значение и может уведомлять подписчиков об изменении этого значения. Следующий код преобразует JSON-представление фильма в эквивалентный объект с наблюдаемыми полями:

На рис. 9 показана начальная реализация модели представления. Эта версия поддерживает только получение списка фильмов. Средства редактирования я добавлю позже. Модель представления содержит наблюдаемые свойства для списка фильмов, строку ошибки и текущий жанр.

Рис. 9. Модель представления

Заметьте, что фильмы находятся в observableArray. Как и подразумевает его имя, observableArray действует как массив, уведомляющий подписчиков об изменении своего содержимого.

Функция getByGenre выдает AJAX-запрос серверу на получение списка фильмов, а затем заполняет результатами массив self.movies.

При использовании REST API одна из самых хитрых частей — обработка асинхронной природы HTTP. jQuery-функция ajax возвращает объект, реализующий Promises API. Вы можете задействовать метод then объекта Promise, чтобы установить обратный вызов, инициируемый, когда AJAX-вызов завершается успешно, и еще один обратный вызов, запускаемый при неудачном AJAX-вызове:

Привязки данных

Теперь, когда у меня есть модель представления, я могу связать ее с HTML через привязки данных. Для полного списка жанров, который появляется на левой стороне экрана, я использую следующие привязки данных:

На данный момент щелчок названия жанра ни к чему не приводит, поэтому я добавляю привязку click для обработки событий щелчка:

Чтобы отобразить список фильмов, я добавил привязки в таблицу, как показано на рис. 10.

Рис. 10. Добавление привязок в таблицу для отображения списка фильмов

На рис. 10 привязка foreach перебирает в цикле массив объектов movie. Внутри foreach привязки text ссылаются на свойства текущего объекта.

Привязка visible в элементе

контролирует, визуализируется ли таблица. Таблица будет скрыта, если массив movies пуст.

Наконец, вот привязки для сообщения об ошибке и сообщения «No records found» (заметьте, что вы можете помещать в привязку сложные выражения):

Редактирование записей

Последняя часть этого приложения дает возможность пользователю редактировать записи в таблице. Для этого необходима следующая функциональность:

Чтобы отслеживать режим просмотра/редактирования, я добавил булев флаг в объект movie как наблюдаемое свойство:

Мне нужно было, чтобы таблица фильмов отображала текст, когда свойство editing равно false, но переключалась на элементы управления вводом, когда оно — true. Для этого я использовал Knockout-привязки if и ifnot, как показано на рис. 11. Синтаксис « » позволяет включать привязки if и ifnot без их размещения внутри элемента HTML-контейнера.

Рис. 11. Поддержка редактирования записей о фильмах

Привязка value задает значение элемента управления вводом. Это двухсторонняя привязка, поэтому, когда пользователь вводит что-то в текстовое поле или изменяет выбор в раскрывающемся списке, изменение автоматически распространяется на модель представления.

Я связал обработчики щелчка кнопок с функциями save, cancel и edit в модели представления.

Функция edit проста. Достаточно установить флаг editing в true:

Функции save и cancel немного посложнее. Для поддержки отмены мне нужен был какой-то способ кеширования исходного значения при редактировании. К счастью, Knockout упрощает расширение поведения наблюдаемых объектов. В коде на рис. 12 добавляется функция store в класс observable. Вызов функции store из observable придает этому классу две новые функции: revert и commit.

Рис. 12. Расширение ko.observable функциями revert и commit

Теперь я могу вызвать функцию store, чтобы добавить эту функциональность в модель:

Рис. 13 демонстрирует функции save и cancel в модели представления.

Рис. 13. Добавление функций save и cancel

Создание веб-клиента с применением Ember

Для сравнения я написал другую версию своего приложения, используя библиотеку Ember.js.

Ember-приложение начинает с таблицы маршрутизации (routing table), которая определяет навигацию пользователя в рамках приложения:

Первая строка кода создает Ember-приложение. Вызов Router.map создает три маршрута. Каждый маршрут соответствует URI или шаблону URI:

Для каждого маршрута вы создаете HTML-шаблон, используя библиотеку шаблонов Handlebars.

В Ember имеется шаблон верхнего уровня для всего приложения. Этот шаблон подвергается рендерингу для каждого маршрута. На рис. 14 показан шаблон application для моего приложения. Как видите, этот шаблон в основном является HTML-кодом, размещаемым в теге script с type=»text/x-handlebars». Шаблон содержит специальную разметку Handlebars в двойных фигурных скобках: << >>. Эта разметка служит той же цели, что и атрибут data-bind в Knockout. Например, <<#linkTo>> создает ссылку на маршрут.

Рис. 14. Шаблон Handlebars уровня приложения

Теперь допустим, что пользователь переходит к /#/about. Это активирует маршрут about. Ember сначала осуществляет рендеринг шаблона application верхнего уровня, затем шаблона about в <> шаблона application. Вот шаблон about:

На рис. 15 показано, как выполняется рендеринг шаблона about в шаблоне application.

одностраничное веб приложение пример. dn463786.wassonspa1113 figure 17 hires(ru ru,msdn.10). одностраничное веб приложение пример фото. одностраничное веб приложение пример-dn463786.wassonspa1113 figure 17 hires(ru ru,msdn.10). картинка одностраничное веб приложение пример. картинка dn463786.wassonspa1113 figure 17 hires(ru ru,msdn.10).
Рис. 15. Рендеринг шаблона about

Поскольку у каждого маршрута свой URI, история браузера сохраняется. Пользователь может осуществлять навигацию кнопкой Back, а также обновлять страницу, не теряя контекст или закладку, и перезагружать ту же страницу.

Контроллеры и модели в Ember

В Ember каждый маршрут имеет модель и контроллер. Модель содержит данные предметной области. Контроллер действует как прокси для модели и хранит все данные состояния приложения для представления. (Это не совпадает с классическим определением MVC. В некоторых отношениях контроллер больше похож на модель представления.)

Вот как я определил модель movie:

Контроллер наследует от Ember.ObjectController (рис. 16).

Рис. 16. Контроллер Movie наследует от Ember.ObjectController

Здесь происходит кое-что интересное. Во-первых, я не указывал модель в классе контроллера. По умолчанию маршрут автоматически устанавливает модель в контроллере. Во-вторых, функции save и cancel используют средства транзакций, встроенные в класс DS.Model. Для отмены изменений просто вызовите функцию rollback модели.

Ember использует массу соглашений по именованию для подключения различных компонентов. Маршрут genres взаимодействует с GenresController, который выполняет рендеринг шаблона genres. По сути, Ember будет автоматически создавать объект GenresController, если вы его не определили. Однако вы можете переопределять все, что предлагается по умолчанию.

В своем приложении я сконфигурировал маршрут genres/movies на использование другого контроллера, реализовав точку подключения (hook) renderTemplate. Тем самым несколько маршрутов может использовать один и тот же контроллер (рис. 17).

Рис. 17. Несколько маршрутов могут иметь общий контроллер

Одна из приятных особенностей Ember в том, что многое можно делать с помощью минимума кода. Мое приложение-пример состоит примерно из 110 строк кода на JavaScript. Эта версия короче, чем версия на основе Knockout, и вдобавок я безо всяких усилий получил поддержку истории браузера. С другой стороны, Ember также является весьма «своенравной» инфраструктурой. Если вы не пишете код в стиле Ember, то скорее всего попадете в неприятности. Так что при выборе инфраструктуры следует принимать во внимание набор функциональности, стиль кодирования и то, насколько общая архитектура инфраструктуры подходит под ваши требования.

Где узнать больше

В этой статье я показал, как JavaScript-инфраструктуры упрощают создание SPA. Попутно я рассказал о некоторых общих средствах этих библиотек, в том числе о связывании с данными, маршрутизации и шаблонах MVC и MVVM. Узнать больше о создании SPA с помощью ASP.NET можно по ссылке asp.net/single-page-application.

Майк Уоссон (Mike Wasson) — программист и технический писатель в Microsoft. Многие годы занимался документированием мультимедийной части Win32 API. В настоящее время пишет о ASP.NET с основным акцентом на Web API. С ним можно связаться по адресу mwasson@microsoft.com.

Выражаю благодарность за рецензирование статьи эксперту Microsoft Хиньяну Чу (Xinyang Qiu).

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *