Я начинаю работать с Browser.application Элма, что очень весело, но одна вещь, которая (насколько я могу судить) никогда толком не объясняется, - это тип Browser.Navigation.Key.

Документы по вязу говорят

Клавиша навигации необходима для создания команд навигации, изменяющих URL-адрес. Сюда входят pushUrl, replaceUrl, назад и вперед.

И я думаю, что на данный момент я думаю, что в значительной степени понял, как его использовать, из следующих примеров в руководстве по вязу, но мне очень любопытно, просто с академической точки зрения:

  • Какого рода информацию содержит этот тип?
  • Как эта информация используется системой навигации elm для внутренних целей?
elm
11
Eleanor Holley 22 Фев 2021 в 04:38

1 ответ

Лучший ответ

Я давно не использовал Elm, но мне самому было любопытно.

На первый взгляд, ключевой механизм решает описанную здесь проблему: https://github.com/elm/browser/blob/1.0.2/notes/navigation-in-elements.md - или, по крайней мере, имеет какое-то отношение к этому утверждению.

Непосредственный вывод заключается в том, что они хотели запретить вам доступ к API изменения URL-адресов, если вы не создали свое приложение с помощью Browser.application, поэтому один из способов сделать это - потребовать в качестве входных данных фиктивный тип, например Key. что вы можете получить, только если используете Browser.application. Но это еще не все.

Browser.application, в отличие от Browser.document и Browser.element, дает вам дополнительные обработчики: onUrlRequest и onUrlChange.

Итак, как это передается вашему приложению при изменении URL-адреса? Как это реализовано?

Исходный код здесь многое объясняет: var key = function() { key.__sendToApp(onUrlChange(_Browser_getUrl())); };

Когда вы используете Browser.application, код инициализации связывает слушателей изменения URL-адреса для вызова key():

_Browser_window.addEventListener('popstate', key);
_Browser_window.addEventListener('hashchange', key);

А функции изменения URL также вызывают key():

var _Browser_pushUrl = F2(function(key, url)
{
    return A2(__Task_perform, __Basics_never, __Scheduler_binding(function() {
        history.pushState({}, '', url);
        key();
    }));
});

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

Это все еще не дает мне полного ответа на одну техническую часть вопроса: зачем вам передавать ключ в Navigation. {Go, push, replace}? Разве приведенный выше код (_Browser_window.addEventListener('popstate', key)) уже не вызывает key() при изменении URL-адреса?

Оказывается, событие popstate срабатывает только при таких взаимодействиях пользовательского интерфейса, как нажатие кнопки возврата. Событие не вызывается, когда вы напрямую используете history.{push,replace}State(..., url), что, конечно же, и делает эта библиотека: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate

Другими словами, похоже, что ключевой механизм существует как простой способ без сохранения состояния для функций go, pushUrl, replaceUrl (https://githnel.com/elm/browser/blob/956e3ec/browser/blob/956e3d3e/ec/d6e6e6e/ec/d6e6e/ec/blob/cd6e/ .js # L190-L212), чтобы иметь возможность вызывать onUrlChange текущего запущенного приложения. В противном случае API, вероятно, смог бы обойтись только строкой _Browser_window.addEventListener('popstate', key) в инициализации Browser.application. Но это событие никогда не генерируется при изменении URL-адреса из Javascript, поэтому им нужен был способ вызова app.onUrlChange() непосредственно внутри этих функций, иначе key().

И, конечно же, у него есть дополнительная выгода, заключающаяся в том, что API URL ограничивается только приложениями, созданными с помощью Browser.application. Немного бессвязный ответ, но у меня не было времени написать более короткий. ;)

12
danneu 22 Фев 2021 в 04:25