Как обслужить правильную панель в рефрейминге на основе uri?

У меня есть несколько панелей, определенных для моего приложения:

(defmulti panels identity)
(defmethod panels :panel1 [] [panel1])
(defmethod panels :panel2 [] [panel2])
(defmethod panels :panel3 [] [panel3])

Я могу использовать bidi + pushy на стороне клиента, чтобы протолкнуть маршрут, скажем, / panel1-uri, когда происходит событие (в данном случае щелкните), и изменить панель с помощью отправки. Но когда я обращаюсь к localhost: 5000 / panel1-uri напрямую через браузер, это не работает, поскольку на сервере не существует маршрута / panel1-uri.

Поэтому я создаю маршрут в моем server / panel1-uri, который просто обслуживает index.html, и добавляю ключ панели, которую я хочу показать, в заголовке ответа этого маршрута. Затем я создаю привязку href к localhost: 5000 / panel1-uri, а не отправляю событие (на push / panel1-uri), но, конечно, это все еще служит панелью по умолчанию. Однако ответ, который я получил при нажатии href, действительно содержит правильный ключ панели в своем заголовке. Как я могу получить доступ к этому заголовку, который я получил из ответа после нажатия href, и использовать его для изменения панели?

В качестве альтернативы, есть ли лучший способ подойти к проблеме обслуживания URI, которые работают не только с событиями на стороне клиента, но и при вводе непосредственно в браузер?


person zengod    schedule 06.03.2020    source источник


Ответы (1)


Я решил эту проблему так же, как и вы:

  • один маршрут /pannel-1 => index.html на стороне сервера,
  • используя pushy для использования истории HTML5.

Вам не нужно передавать данные обратно на клиентскую сторону в заголовке HTTP-ответа. Хитрость в том, что Pushy срабатывает при запуске, поэтому вам просто нужно дождаться загрузки страницы, чтобы вызвать pushy/start!. Другими словами, сначала смонтируйте приложение React, а затем запустите маршрутизатор.

Вот немного моего кода:

(ns my.router
  (:require [pushy.core :as pushy]))

;; We need to call `pushy/start!` as the last action in the boot process or it
;; might produce unexpected behavior. Pushy uses goog.history, and the goog
;; history need to be loaded before the app starts and before the document has
;; finished loading, but triggering the routing mechanism need to be done once
;; the world is set up.
;; @see https://google.github.io/closure-library/api/goog.History.html
(defn start! []
  (pushy/start! history))

В вашем основном пространстве имен:

(ns your.app.core
  (:require [your.app.router :as router]))

(defn ^:export boot! []
  (do-stuff-to-set-up-your-app-state)
  (mount-your-react-app)
  (router/start!))

В вашем index.html:

<script … src="app.js"></script>
<script type="text/javascript">
  your.app.core.boot_BANG_();
</script>
person Geoffrey Gaillard    schedule 06.03.2020
comment
Мне нужно больше подробностей, чтобы понять, что вы имеете в виду. Как это решает проблему отправки правильной панели, когда URL-адрес вводится непосредственно в браузере? - person zengod; 06.03.2020
comment
Вам следует только перенаправить /panel-x на index.html на сервере, а затем забыть о серверной стороне. Далее все происходит на стороне клиента. Когда вы вводите URL-адрес прямо в браузер, он остается там после загрузки страницы index.html. Когда страница загружена, при принудительном запуске bidi обработает фрагмент URL-адреса и вернет вам правильный маршрут на стороне клиента. - person Geoffrey Gaillard; 06.03.2020
comment
Кажется, это работает, но единственное, что при повторном запуске в браузере я вижу не предыдущую страницу, а ту же страницу. То есть, когда меня перенаправляют на / new-uri при нажатии кнопки, я не могу вернуться правильно, но когда я помещаю / new-uri в браузер, я могу. Как это исправить? - person zengod; 06.03.2020
comment
Вы должны быть уверены, что при нажатии на кнопку «назад» среагирует настойчивый (достаточно использовать console.log). Если pushy не реагирует, значит, возникла проблема с его инициализацией. Будьте осторожны, поскольку goog.History устанавливается глобально при загрузке страницы, вы можете выполнить жесткое обновление, чтобы убедиться, что экземпляр истории правильно инициализирован. Если настойчивый реагирует правильно, но ваш компонент не обновляется, это может быть связано с использованием нескольких методов, и вы можете посмотреть stackoverflow.com/questions/33299746/ - person Geoffrey Gaillard; 06.03.2020
comment
Более подробная информация здесь: stackoverflow.com/questions/60712822/ - person zengod; 16.03.2020