Рендеринг шаблона HTML5 в слот веб-компонента из другого файла - PullRequest
0 голосов
/ 16 апреля 2020

Я только начинаю работать с веб-компонентами и пытаюсь абстрагировать повторение кода HTML для своих собственных файлов, так что не так, как я это делаю с <nav-bar> и <bootstrap-wrapper>, но это скорее компонентный подход .

Теперь я хочу структурировать свой проект таким образом, чтобы мой template был отправлен на slot в index.html для рендеринга.

Как я могу отобразить welcome.html внутри моего index.html, а также, как мне затем перейти от welcome.html к другому шаблону

index. html

<!DOCTYPE html>
<html lang="en">

<body>
    <bootstrap-wrapper>
        <nav-bar></nav-bar>
        <span slot="content"></span>
    </bootstrap-wrapper>
</body>

<script src="actio.js"></script>

</html>

actio. js

customElements.define(
  'nav-bar',
  class NavBar extends HTMLElement {
    connectedCallback() {
      this.innerHTML = `
        <nav class="nav">
          <a class="nav-link" href="welcome.html">Home</a>
          <a class="nav-link" href="enter-names.html">Enter Names</a>
          <a class="nav-link" href="calculator.html">Calculator</a>
          <a class="nav-link" href="history.html">History</a>
        </nav>
      `;
    }
  }
);

const template = document.createElement('template');
template.innerHTML = `
    <div class="container">
      <div class="row">
        <div class="col-sm-12 col-md-8 col-lg-6">
          <div class="jumbotron bg-dark text-white">
            <p><slot name="content" /></p>
          </div>
        </div>
      </div>
    </div>
`;

customElements.define(
  'bootstrap-wrapper',
  class BootstrapWrapper extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({
        mode: 'open'
      }).appendChild(
        template.content.cloneNode(true)
      );
    }
  }
);

Добро пожаловать. html

<template class="welcome">
    <h1>Household Budget Calculator</h1>
    <h3>No more arguments about how to divide your household expenses!</h3>
    <h4>How it works:</h4>
    <ol>
        <li>Enter names</li>
        <li>Fill household expenses</li>
        <li>Each of you fills in their income</li>
        <li>Hit Calculate</li>
        <li>Enjoy a blissful partnership!</li>
    </ol>

    <button onclick="location.href='enter-names.html'"
            type="button"
            class="btn btn-primary">Enter Names</button>
</template>

Ответы [ 2 ]

2 голосов
/ 17 апреля 2020

Используйте fetch(), который является асинхронной функцией.

В своем классе BoostrapWrapper добавьте метод:

async function loadTemplate( filename ) {
    var response = await fetch( filename )
    var text = await response.text()
    this.querySelector( span[slot=content]' ).innerHTML = text
}

Нет необходимости включать код в <template> элемент, если вы не используете Javascript код внутри. В последнем случае вам потребуется создать временный элемент <template>.

Затем вы можете вызвать метод с любым файлом HTML.

0 голосов
/ 23 апреля 2020

Используя fetch() Я реализовал метод с именем createComponent(), который берет путь и выбирает файл HTML, который содержит <template> и добавляет его к #app-root в моем index.html

main. js

function createComponent(path) { // path is relative to root of project

  fetch(path)
    .then(function (response) {
      return response.text();
    })
    .then(function (html) {
      const doc = new DOMParser().parseFromString(html, 'text/html');
      const template = doc.querySelector('head > template');

      document.querySelector('#app-root').innerHTML = '';
      document.querySelector('#app-root').appendChild(template.content);
    })
    .catch(function (err) {
      console.error('Something went wrong.', err);
    });
}

index. html

<!DOCTYPE html>
<html lang="en">

<body>
    <span id="app-root">
        <!-- APP ROOT -->
    </span>
</body>
<script src="main.js"></script>

</html>

template. html

<template>
    <div class="welcome">
        <h2>Welcome to the Household Budget Calculator</h2>
        <p>We help you divide household expenses fairly.</p>
        <h4>How it works:</h4>
        <ol>
            <li>Enter names</li>
            <li>Fill household expenses</li>
            <li>Each of you fills in their income</li>
            <li>Hit Calculate</li>
            <li>Enjoy a blissful partnership!</li>
        </ol>
        <div class="button-area">
            <button onclick="next()">Next</button>
        </div>
    </div>
</template>
...