Как вставить и вложить компонент в другой в ractive.js, когда компоненты находятся в двух отдельных файлах?

Я изучал ractive.js в течение нескольких недель, и я пытаюсь создать функцию на большой веб-странице, которая перечисляет три элемента. Каждый список имеет свое собственное название и описание. Каждый список является компонентом (list-component) со своими собственными стилями и javascript (каждый компонент представляет собой отдельный html). У меня также есть компонент (description-component), который отвечает за запись заголовка и описания, и он находится в отдельном html-файле. Проблема, с которой я столкнулся, заключается в "импорте" или внесении этого компонента-описания в список-компонент, поэтому вывод в HTML-файле основного индекса выглядит так:

<description title="Name">
    <list-items/>
</description>

До сих пор я изучал директиву yield и пробовал несколько примеров, но это был простой пример, использующий два компонента в одном документе. Я не уверен, что это правильный путь. Вот что находится в html-файле description-component:

<p>{{title}}</p>

Я попытался использовать ractive-load.js и загрузить html компонента описания для каждого файла списка компонентов, как в этом примере на их github:

Ractive.load({
  Foo: 'my-components/foo.html',
  Bar: 'my-components/bar.html'
}).then( function ( components ) {
  var foo = new components.Foo({
    el: 'body',
    data: { ... }
  });

  var bar = new components.Bar({
    el: 'body',
    data: { ... }
  });
}).catch( handleError );

и это казалось излишним и думал, что должен быть лучший путь. Как бы я подошел к этому?

1 ответ

Решение

Загрузка компонентов Ractive напрямую не связана с обработкой вложенных компонентов и передачей полученного содержимого компонентам.

Ractive.load работает, выбирая один или несколько HTML-файлов, которые затем преобразуются в Компоненты. Судя по вашим примерам кода, эта часть работает. Для больших приложений я обычно использую плагин инструмента сборки, чтобы предварительно связать все мои компоненты Ractive, чтобы они могли быть доставлены в одном файле или даже свернуты в мой основной комплект js.

Несмотря на то, что компоненты доступны, их необходимо зарегистрировать либо в компоненте-потребителе (или в родительском представлении), либо в глобальном масштабе:

Ractive.load({
  Foo: 'my-components/foo.html',
  Bar: 'my-components/bar.html'
}).then( function ( components ) {
  Ractive.components.foo = components.Foo;
  Ractive.components.bar = components.Bar;

  // now create your actual top-level view instance(s)

}).catch( handleError );

В архитектурах компонентов вы создаете деревья или кусты компонентов. У меня обычно только один верхний уровень app компонент, но, безусловно, возможно создать несколько деревьев, которые начинаются в разных местах в DOM.

Для простоты, продолжая приведенный выше пример, давайте создадим общий экземпляр ractive, который использует два зарегистрированных нами компонента Foo и Bar (обратите внимание, что мы используем имя свойства, которое мы присвоили Ractive.components):

const ractive = new Ractive({
    el: document.body,
    sayHello() {
        alert('hello from main Ractive instance');
    },
    template: `
        <h1>my kewl app</h1>
        <foo>
            <h3 on-click="sayHello()">hello world</h3>
            <bar bizz="{{buzz}}"></bar>
        </foo>
    `
});

В этом случае мы передаем некоторый контент (html и наш компонент bar) компоненту foo, включив его в качестве <foo> содержание элемента.

Как этот контент используется, зависит от foo шаблон. Есть два варианта:

<div>
    <h2>foo component template</h2>
    {{>content}}
    <p>some more stuff</p>
</div>

В этом примере мы используем встроенный частичный "контент", чтобы сказать шаблону поместить предоставленный контент в {{>content}} слот. В этом случае предоставленный контент передается как частичный, и любые директивы будут применяться к foo составная часть. Таким образом, в этом примере, нажав на заголовок h3 попытается запустить foo.sayHello(), И при прохождении bizz данные к bar компонент, Ractive начнет искать в foo компонент для buzz,

Часто это не то, что вы хотите. Что бы вы предпочли, так это чтобы родители владели директивами. Так что вместо foo шаблон будет выглядеть так:

<div>
    <h2>foo component template</h2>
    {{yield}}
    <p>some more stuff</p>
</div>

А теперь когда h3 щелкает, он вызывает основной ractive.sayHello() Метод, поскольку содержимое было передано для отображения в DOM компонентом foo, но оно все еще принадлежало передающему экземпляру. Аналогично Ractive начнёт искать buzz в основном не foo,

С yield Вы также можете назвать несколько партиалов для передачи:

<!-- "foo" template: -->
<div>
    <header>{{yield header}}</header>
    <section>
        <div>something here</div>
        <div>{{yield message}}</div>
    </section>
</div>

<!-- using "foo": -->
<div>
    <foo>
        {{#partial header}}
            <h2>This is the header to use</h2>
        {{/partial}}
        {{#partial message}}
            <p>This is the message to use, with a bar component to boot</p>
            <bar></bar>
        {{/partial}}
    </foo>
</div>
Другие вопросы по тегам