Turbo-Rails: Как я могу добавить Turbo Frame в `application.html.erb`?

Я выполнил следующее в командной строке:

> 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-файл, показывающий решение, которое работает с двумя турбокадрами, одно из которых сохраняется на всех страницах:

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
184
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При навигации во фрейме ваш макет 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>

Спасибо @alex за подробный ответ, особенно за ссылки на код turbo-rails! Что, если я делаю больше в макете application, например, отрисовываю боковую панель, которая также использует турбо. Я хочу, чтобы эта боковая панель была на каждой странице, но я не хочу, чтобы Turbo повторно отображал боковую панель при повторном отображении основного контента, и наоборот. Что было бы хорошим способом сделать это? Смотрите здесь для примера.

a-lavis 03.04.2023 15:19

Обновление: я нашел способ сделать это, но мне интересно, знает ли кто-нибудь лучший способ сделать это. Смотрите обновление в основном вопросе.

a-lavis 03.04.2023 19:26

@a-lavis смотрите обновление. я бы сказал, постарайтесь не усложнять, просто визуализируйте макет application, вы можете оптимизировать позже и визуализировать только ту часть, которая вам нужна.

Alex 03.04.2023 19:53

Другие вопросы по теме