Я выполнил следующее в командной строке:
> rails new test-turbo
> rails g controller Home index
Добавлен следующий маршрут к config/routes.rb
:
resources :home, only: [:index]
Заключил <%= yield %>
в app/views/layouts/application.html.erb
в тег турбокадра:
<body>
<%= turbo_frame_tag :foobar do %>
<%= yield %>
<% end %>
</body>
Добавил ссылку в app/views/home/index.html.erb
:
<%= link_to "Link to this page", home_index_path %>
Затем, когда я нажимаю на эту ссылку, я получаю ошибку турбокадра:
Если я перемещу тег турбокадра на домашнюю/индексную страницу, он будет работать нормально:
app/views/home/index.html.erb
<%= turbo_frame_tag :foobar do %>
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= link_to "Link to this page", home_index_path %>
<% end %>
Почему это работает, а вставить app/views/layouts/application.html.erb
не получается? Он генерирует один и тот же HTML в конце дня, верно?
Если это будет полезно, вот репозиторий GitHub. Коммит 537c40a
имеет ошибку, коммит b42ca66
работает нормально.
Обновление: вот GIF-файл, показывающий решение, которое работает с двумя турбокадрами, одно из которых сохраняется на всех страницах:
При навигации во фрейме ваш макет application
не отображается. Что видно из логов:
Rendered home/index.html.erb within layouts/turbo_rails/frame (Duration: 0.1ms | Allocations: 38)
Вы смотрите на инспектора и <turbo-frame id = "foobar">
, когда вы нажимаете на ссылку, HTML-код текущей страницы не заменяется HTML-кодом ответа, в этом весь смысл фрейма. Обновляется только содержимое внутри фрейма. Вы можете увидеть фактический ответ на вкладке сети:
Турбо кадра в ответе нет ^
Чтобы отобразить макет, вы можете явно установить его в контроллере на переопределение макета Turbo Frame ️:
layout "application"
Просто к вашему сведению, в компоновке очень мало необходимости в турбо-раме, особенно в той, которая охватывает все вокруг. <body>
элемент уже ведет себя как фрейм, и другой фрейм прямо под ним ничего вам не даст.
Обновлять
Возможно, иметь целый контроллер — это слишком. Я бы начал с чего-то простого. Самый простой способ — всегда отображать макет application
. Пропуск рендеринга макета — это всего лишь оптимизация для ускорения работы, все, что находится за пределами кадра, в любом случае отбрасывается.
Вы можете добавить немного if..else
к макету:
...
<body>
<% unless request.headers["Turbo-Frame"] == "main_content" %>
<%= turbo_frame_tag :side_bar do %>
# TODO: sidebar
<% end %>
<% end %>
<%= turbo_frame_tag :main_content do %>
<%= yield %>
<% end %>
</body>
Обновление: я нашел способ сделать это, но мне интересно, знает ли кто-нибудь лучший способ сделать это. Смотрите обновление в основном вопросе.
@a-lavis смотрите обновление. я бы сказал, постарайтесь не усложнять, просто визуализируйте макет application
, вы можете оптимизировать позже и визуализировать только ту часть, которая вам нужна.
Спасибо @alex за подробный ответ, особенно за ссылки на код
turbo-rails
! Что, если я делаю больше в макетеapplication
, например, отрисовываю боковую панель, которая также использует турбо. Я хочу, чтобы эта боковая панель была на каждой странице, но я не хочу, чтобы Turbo повторно отображал боковую панель при повторном отображении основного контента, и наоборот. Что было бы хорошим способом сделать это? Смотрите здесь для примера.