Как создать компоненты, которые могут принимать позиционные дочерние элементы в качестве аргументов (Dart)?

Я ищу ресурсы о том, как создавать веб-компоненты, которые могут принимать позиционные дочерние аргументы. Что-то вроде:

<x-editable-component>
  <span>{{value}}</span> // this could be any uneditable element
  <textarea>{{value}}</textarea> //could be any editable element
</x-editable-component>

Приведенный выше элемент будет отображать интервал в редактируемом == false, а текстовое поле в редактируемом == true editable - это глобально наблюдаемая статическая переменная.

Я думаю, что было бы возможно получить такого рода составное поведение с наследованием. Тем не менее, мне было интересно, возможно ли сделать это способом компоновки, упомянутым выше. Если компонент (x-editable-component) просто ожидает двух дочерних элементов, один дочерний элемент будет отображаться при редактировании, а другой дочерний - при недоступности для редактирования.

Чтобы было ясно, я хочу, чтобы любые два дочерних элемента были написаны как дочерние элементы x-editable-component, поэтому, возможно, где-то еще ниже у меня есть компонент x-editable, написанный так.

<x-editable-component>
  <div>{{value}}</div> // this could be any uneditable element
  <input>{{value}}</input> //could be any editable element
</x-editable-component>

Это возможно?

1 ответ

Решение

Это звучит как хорошее применение для <content> тег.

<element name="my-editable-component">
  <template>
    <div style="display: {{editing ? 'block' : 'none'}}">
      <content select=".editing"></content>
    </div>
    <div style="display: {{editing ? 'none' : 'block'}}">
      <content select=".normal"></content>
    </div>
  </template>
  <script type="application/dart">
    class MyEditableComponent extends WebComponent {
      bool editing = false;
      // ...
    }
  </script>
</element>

Здесь я использую классы, но вы можете придумать любой протокол, какой захотите. <content select=""> можно использовать большинство селекторов CSS.

Это будет использоваться как:

<my-editable-component>
  <div class="normal">{{value}}</div>
  <input class="editing">{{value}}</input>
</my-editable-component>

Более подробную информацию о "контенте" можно найти в статье о веб-интерфейсе, или вы можете увидеть пример в спецификации shadowdom.

Пожалуйста, обратите внимание: я использую display: none вместо <template if> для обхода проблемы https://github.com/dart-lang/web-ui/issues/228

Другие вопросы по тегам