Как работает router: небольшая статья

Коллеги, накопилась информация, которой нет в едином виде ни в документации, ни на форуме касательно роутера. Не для новичков, а для тех, кто хочет глубже понять как устроен роутинг в F7. Не буду спамить ссылками, поэтому выкладываю здесь. Очень рад фидбеку и указанием на ошибки.


SwipeBack

По умолчанию Framework7 всегда держит в DOM предыдущую страницу, если она есть, конечно. Состояние этой предыдущей страницы полностью сохраняется.

При навигации “назад” каждый раз загружается предыдущая страница. Допустим, у нас есть переходы:

page1 > page2 > page3

Если, находясь на page3, мы нажимаем “назад”, то перед тем, как показать page2, которая у нас уже есть в DOM, мы загружаем страницу page1 и кладем ее в DOM. Когда мы уже на page2, то действие “назад” ничего не загружает и сразу показывает page1.

На такое поведение влияют две опции: SwipeBack (для каждой темы - свой параметр) и preloadPreviousPage.

Загрузка предыдущей страницы с помещением ее в DOM будет работать когда включено preloadPreviousPage или когда включен SwipeBack.

Сам SwipeBack (жест слева направо) полноценно будет работать всегда, когда включена сама опция SwipeBack, а preloadPreviousPage в этом случае может принимать любое значение.

Особенность ios и Navbar

В ios-теме Navbar, при навигации на страницу (или другую сущность), удаляется из текущего места и поднимается вверх на уровень View. Поэтому всегда при обращении к Navbar используйте метод app.navbar.getElByPage(pageEl), где pageEl, например, для текущей страницы можно получить так: app.views.current.router.currentPageEl

stackPages в View

В View можно установить параметр stackPages=true (по умолчанию он выключен), который сделает возможным сохранять предыдущие страницы в DOM вместе с их состоянием.

Сохранение работает только “назад”, но можно сделать и “вперед”, об этом в следующем разделе.

Пример того, когда состояние сохранится: page1 > page2 (что-то сделали) > page3 > (вернулись) page2 (состояние сохранилось).

Пример того, когда состояния не сохранилось: page1 > page2 > page3 (что-то сделали) > (вернулись) page2 > page3 (состояние не сохранилось).

В большинстве случаев, если нам нужен такой функционал, мы просто включаем эту опцию в любой момент и получаем сохранение состояния.

Данные при stackPages=true хранятся в DOM, учитывайте это обязательно.

Пара слов о роутере

Роутер устроен так, что данные он получает только один раз и не важно, каким откуда именно пришли данные, кроме динамического контента, т.к. content. Например, компонент роутера будет загружен только один раз.

el и PageName

Есть много вариантов, откуда брать контент в конкретном маршруте, но тут не все так просто.

Для полноценной и правильной работы el и pageName:

  • Это может быть только страница, т.е. <div class="page"></div>
  • У текущего View параметр stackPages должен быть включен.
  • Элемент должен быть в текущем View, а не где-то за его пределами в DOM.
  • У элемента должен быть класс stacked, т.е. так <div class="page stacked"></div>

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

el

Роутер ищет этот элемент в любом месте DOM, извлекает его оттуда и делает его текущей страницей.

pageName

Роутер ищет <div class="page" data-name="{{pageName}}"></div> только в текущем View. Он извлекает элемент из DOM навсегда и делает его текущей страницей.

KeepAlive

Любой маршрут из списка routes может иметь опцию keepAlive : true. В этом случае то, что загрузилось по этому маршруту закешируется раз и навсегда. Кеширование не зависит от параметров маршрута, а также привязывается именно к маршруту, а не ко View, ведь можно открыть один и то же маршрут в разных View.

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

Кеширование работает при навигации и вперед и назад. Кешируемые данные не сохраняются в DOM, а находятся в переменной, которая отвечает за данный маршрут. Средств для очистки кеша нет.

KeepAlive работает только со страницами, т.е. с <div class="page"></div>

6 Likes

Спасибо!

Тут немного не так. Сначала мы возвращаемся на page2, а потом (когда мы уже на page2) загружается page1. В остальном всё верно :+1:

спс большое, побольше бы таких статей и про Template7 для блондинок :wink:

T7 прост, там в доках все есть, что еще можно написать даже не знаю.

при первом взгляде я даже не стал его использовать, теперь лень переписывать всё просто, а если бы была статья, то это другое дело, изначально пытался найти информацию про framework7 на русском языка, про тот же ionic её в разы больше, а про сам framework7 узнал прочитав на habre

было бы интересно посмотреть на практические примеры реализации каких-либо задач

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

Советую смотреть под другим углом, это же JS, соответственно примеров в инрентах навалом. Если конкретно про F7 то в YouTube много интересно.

Гугл переводчик тоже забанил? )) В YouTube что то было на русском

1 Like

Рекомендую почитать доку, в связке с $setState решает все задачи, которые мне встречались в проектах.

https://framework7.io/templates/ также поиграйтесь с F7 cli, тогда будет больше понимания, как правильно делать под Кордову

Нет, да и не нужно, дока не сложная. Вот что-то типа “лучшие практики” - это вот не хватает, особенно с роутером, т.к. нужно его очень хорошо понимать, если писать что-то большое.

Нет, да и не нужно, дока не сложная

Все относительно. Мне показалось сложным. Прочитал примерно треть из доков (по порядку следования), понял какие-то моменты, установил npm и framework7, создал проект, поотвечал на вопросы, запустил… А дальше что? - какой файл открыть и что в нем нужно написать, чтоб появилась новая кнопочка с алертом “Hello World”.

Я про доку к Template7, а не к Framework7

В изучении/освоении документации, я бы посоветовал метод “идти от обратного” :smiley:

app.dialog.alert(text, title, callback)- create Alert Dialog and open it
  • Что такое app? Чуть выше есть http://framework7.io/docs/dialog.html#dialog-shortcuts-parameters Значит это там где у нас в коде app = new Framework7(...);
  • Значит там мы можем добавить добавить обработчик события нажатия кнопки и вызвать app.dialog.alert

Это вкратце. А вообще чтобы не терять много времени на основах, где и что, лучше сразу писать сюда на форум. На простые вопросы тут отвечают быстро :wink:

Прошу прощения, учусь кодить дальше и есть вопрос по этому пункту:

Так вот, если я на page1 через AJAX уже подгрузил результаты на страницу и с нее пользователь переходит на page2 и возвращается обратно - то все ОК, но вот если он с page2 далее переходит на page3 и потом идет обратно, то главная страница (page1) уже “сбрасывается” и все результаты AJAX “слетают”.
Вопрос в следующем, как нужно написать конструкцию в app.js или в routes.js, чтобы главная оставалась без изменений?

var routes = [
// Index page
{
path: '/',
url: '/',
},
},

2 варианта: keepAlive и stackPages - об этом в стартовом посте

1 Like

Присоединяйтесь в Телеграм-чат: https://t.me/framework7ru

1 Like

Спасибо, все теперь работает так, как нужно. Моя загвоздка была еще в том, что я писал “stackPages: true” в routes.js, а нужно было в app.js. надеюсь это кому-то поможет!