Под гидратацией понимается процесс добавления сценария JavaScript обратно в скомпилированный HTML-код страницы во время рендеринга HTML-кода в браузере.
Например, если на странице есть два компонента, которые при рендеринге рассматриваются как главный/подчиненный, то для обновления подчиненного компонента необходимо нажать на соответствующий элемент в главном компоненте. Все это обрабатывается кодом JavaScript, исполняемым на странице. Чтобы выполнить эту работу, необходимо гидратировать HTML-код двух компонентов после их рендеринга на странице, добавив обработчик событий on click
к элементам в главном компоненте и прослушиватель в контейнере подчиненного компонента для повторного рендеринга при возникновении события on click
на основе полезных данных, переданных в событии.
Компиляторы компонентов вставляют HTML-код в страницу. Если для добавления таких объектов, как обработчики событий, необходимо во время выполнения исполнить дополнительный код JavaScript, то у вас есть несколько вариантов: встроенный JavaScript или функция гидратирования. Выбор решения зависит от ваших требований.
Можно вставить тег <script> непосредственно в возвращенную скомпилированную разметку. Данный сценарий будет выполняться по мере выполнения страницы.
Пример:
<script src="/_sitesclouddelivery/renderer/libs/scs-core/jssor- slider/js/jssor.slider.min.js" type="text/javascript"></script> <div id="slider_container_c46b122d-978a-429d-aa25-9b5698428f6f" style="position: relative; top: 0px; left: 0px; height: 400px; width: 600px; background-color: rgb(68, 68, 68); visibility: visible;" data-jssor- slider="1"> . . . </div> <script> (function () { // get the required options var options = {"$FillMode":2,"$AutoPlay":false,"$AutoPlayInterval":3000,"$SlideDuration":50 0,"$ArrowKeyNavigation":true,"$HWA":false,"$BulletNavigatorOptions":{"$Chance ToShow":1,"$AutoCenter":1,"$SpacingX":5},"$ArrowNavigatorOptions":{"$ChanceTo Show":1,"$AutoCenter":2,"$Steps":1},"$ThumbnailNavigatorOptions":{"$ChanceToS how":0,"$DisplayPieces":7,"$SpacingX":8,"$ParkingPosition":240}}; // select the JSSOR value options options.$BulletNavigatorOptions.$Class = $JssorBulletNavigator$; options.$ArrowNavigatorOptions.$Class = $JssorArrowNavigator$; options.$ThumbnailNavigatorOptions.$Class = $JssorThumbnailNavigator$; // create the slider var slider = new $JssorSlider$("slider_container_c46b122d-978a- 429d-aa25-9b5698428f6f", options); // resize, maintaining aspect ratio var container = slider.$Elmt.parentElement; if (container) { slider.$ScaleWidth(container.getBoundingClientRect().width); } })(); </script>
Вместо ввода кода JavaScript в файл render.js
можно включить функцию гидратации и отметить, что при возврате скомпилированной разметки компоненту требуется гидратация во время выполнения. Гидратация позволяет избежать повторяющихся тегов <script>
и использовать существующий код JavaScript для управления событиями.
Несмотря на то, что файл render.js
загружен, функция render()
не вызывается во время гидратации. Вызывается только функция hydrate()
.
Примечание.:
Если скомпилированному компоненту не требуется гидратация, файлrender.js
компонента никогда не загружается.Например, пользовательский компилятор макетов контента возвращается с кодом - { hydrate: true
}.
return Promise.resolve({ content: compiledContent, hydrate: true // note that we want to hydrate this component using the render.js hydrate() function. This is required for when the user clicks on the author });
Кроме того, при необходимости пользовательский компилятор может добавлять свойства hydrate, которые он ищет во время выполнения. Пример:
Compiler: // calculate the hydrate data content.hydrateData = JSON.stringify({ contentId: content.id, authorName: content.fields['starter-blog-author_name'] }); . . . Template: <div class="author-container" data-hydrate="{{hydrateData}}">
Наконец, если компоненту требуется гидратация, во время выполнения загружается файл render.js
компонента и вызывается функция hydrate()
, которая передается в контейнере <div>
, содержащем скомпилированную разметку.
Например, render.js
— см. функцию hydrate()
:
function selectAuthor(parentObj, contentId, authorName) { var $parentObj = $(parentObj); $parentObj.find(".author-name").click($.proxy(function () { $(".author-name").removeClass('author-selected'); $(event.target).addClass('author-selected'); }, self)); if (window.location.href.indexOf("default=" + contentId) >= 0) { $(".author-name").each(function () { if (this.innerText === authorName) { $(this).addClass('author-selected'); } }); } } . . . hydrate: function (parentObj) { var $parentObj = $(parentObj), hydrateData = $parentObj.find('.author-container').attr('data- hydrate'); if (hydrateData) { var data = JSON.parse(hydrateData); selectAuthor(parentObj, data.contentId, data.authorName); } }, render: function (parentObj) { . . . try { // Mustache template = Mustache.render(templateHtml, content); if (template) { $(parentObj).append(template); } selectAuthor(parentObj, this.contentItemData.id, content.fields['starter-blog-author_name']); } catch (e) { console.error(e.stack); } }