как я могу перезагрузить один турбо-кадр и обновить URL-адрес?

Я попытался привести минимальный пример, не связанный с какой-либо конкретной серверной технологией. Итак, я только что сгенерировал веб-страницу с помощью bash и обслужил ее с помощью cgi.

      $ mkdir example
$ cd example
$ cat > index.html
<meta http-equiv="Refresh" content="0; url='/cgi-bin/index.sh'" />

$ mkdir cgi-bin
$ cat > cgi-bin/index.sh
#! /usr/bin/env bash

set -e

echo Content-Type: text/html
echo
sed "s/NEW/$RANDOM/g" << EOF
<html>
  <head>
    <title>DEMO</title>
    <script src="/node_modules/@hotwired/turbo/dist/turbo.es2017-umd.js"></script>
  </head>
  <body>
    <h1>DEMO</h1>
    <p><small>lucky bonus number: $RANDOM</small></p>
    <turbo-frame id='example-frame'>
        <a href="?NEW">NEW turbo frame</a><br />
        <a href="?NEW" data-turbo-frame="_top">NEW full page</a>
        <p>number in query string: $QUERY_STRING</p>
    </turbo-frame>
    <br />
  </body>
</html>
EOF


$ chmod +x cgi-bin/index.sh
$ npm install --save @hotwired/turbo@7.0.1
$ python3 -m http.server --cgi # or whichever server

Это создает веб-страницу, которая выглядит следующим образом:

Затем, когда вы нажимаете ссылку на перезагрузку турбо-кадра, вы получаете следующее:

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

Полностраничная турбо-ссылка делает это:

Он обновляет номер счастливого бонуса (контент за пределами турбо-кадра) и обновляет URL-адрес. (Я уверен, что он работает правильно. Я проверил вкладку сети. Каждый раз выполняется только выборка.)


Что бы я хотел сделать:

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

Поэтому в этом примере я хотел бы увидеть как строку запроса на странице, так и фактическое обновление строки запроса, оставив неизменным только «счастливый бонусный номер».

1 ответ

Это определенно возможно, хотя для этого потребуются некоторые существенные изменения в вашей реализации. По сути, вам нужно использовать Turbo Streams для частичной замены страниц.

  1. Вам нужен второй файл для запроса, у которого есть Content-Type text/vnd.turbo-stream.html.
  2. Частичная перезагрузка страницы отлично работает без Javascript (т.е. оставьте бонусный номер неизменным при обновлении внутри турбо-фрейма), но если вы хотите обновить URL-адрес, вам понадобится JS.

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

без изменений.

веб-страница / cgi-bin / index.html

Здесь я просто поменял теги ссылок. Запросы на полную перезагрузку страницы index.html, где ссылка с включенным турбонаддувом запрашивает template.htmlПо какой-то причине мне нужно было добавить data-turbo = true в ссылку с поддержкой Turbo; быть внутри турбо-рамы было недостаточно. data-turbo-action=replaceПредполагается, что это атрибут HTML, который «заменяет» значение местоположения в URL-адресе. Это не похоже на то, что я ожидаю от документов .

      #! /usr/bin/env bash

set -e

echo Content-Type: text/html
echo
sed "s/NEW/$RANDOM/g" << EOF
<html>
  <head>
    <title>DEMO</title>
    <script src="/node_modules/@hotwired/turbo/dist/turbo.es2017-umd.js"></script>
  </head>
  <body>
    <h1>DEMO</h1>
    <p><small>lucky bonus number: $RANDOM</small></p>
    <turbo-frame id='example-frame'>
        <a href="template.html?NEW" data-turbo="true" data-turbo-action="replace">
          NEW turbo frame
        </a><br />
        <a href="index.html?NEW" data-turbo="false">
          NEW full page
        </a>
        <p>number in query string: $QUERY_STRING</p>
    </turbo-frame>
    <br />
  </body>
</html>
EOF

веб-страница / cgi-bin / template.html

Это самый важный момент. Ваш сервер должен ответить turbo-stream тег, с действием replace (потому что вы хотите заменить HTML-контент) и с целевым атрибутом, установленным на идентификатор вашего турбо-кадра (потому что это контент, который вы хотите заменить).

      #! /usr/bin/env bash

set -e

echo Content-Type: text/vnd.turbo-stream.html; charset=utf-8
echo
sed "s/NEW/$RANDOM/g" << EOF
<turbo-stream action="replace" target="example-frame">
    <template>
        <turbo-frame id='example-frame'>
            <a href="template.html?NEW" data-turbo="true" data-turbo-action="replace">
              NEW turbo frame
            </a><br />
            <a href="index.html?NEW" data-turbo="false">
              NEW full page
            </a>
            <p>number in query string: $QUERY_STRING</p>
        </turbo-frame>
    </template>
</turbo-stream>
EOF

Тестировать:

  1. открыть index.html в браузере
  2. щелкните ссылку «полная страница», обратите внимание, что количество бонусов изменилось, строка запроса теперь находится в URL-адресе и на странице. Вы уже получили эту часть.
  3. щелкните ссылку «турбо-кадр», обратите внимание, что бонусный номер не меняется, строка запроса находится на странице, НО не в URL-адресе. Это еще не все, о чем вы просили, но это уже близко.
  4. откройте DevTools, в консоли JS выполните
      Turbo.visit(`template.html?${<any number here>}`)
for example:
Turbo.visit(`template.html?${new Date().valueOf()}`)

обратите внимание, что бонусный номер не меняется, ссылки получают новые случайные числа, а строка запроса ОБА в URL-адресе и на странице. Вы можете делать это несколько раз и постоянно обновлять турбо-кадр. Это то, о чем вы просили, и, похоже, для этого требуется некоторый JS. Я обновлю свой ответ, если найду какие-либо другие атрибуты html, которые могут устранить необходимость в JS.

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