Как можно жить без наследования в шаблонах закрытия в большом проекте?

Мы используем библиотеку закрытия и компилятор замыкания, и мы хотим использовать шаблоны закрытия.

Но шаблоны закрытия не имеют наследования. Это действительно проблема для нас.

Как я понимаю, причина, по которой шаблоны закрытия не имеют наследования, заключается в том, что шаблоны должны быть простыми и легко читаемыми.

Но как вы можете жить без наследования в больших проектах?

Например, у нас есть шаблонный файл button.soy, который генерирует кнопку с открытым шаблоном project.createButton и приватными шаблонами: project.createOpenTag_, project.createCSSClasses_, project.createAttributes_, project.createContent_, project.createCloseTag_.

У нас есть класс JavaScript project.Button, и мы имеем project.ButtonCircle (возможно, этот отдельный класс project.ButtonCircle кажется ненужным, но это просто пример), который расширяет project.Button.

project.ButtonCircle требует незначительных изменений в шаблоне project.createButton.

Конечно, мы можем добавить новую функциональность в project.createButton, но это очень плохая идея, потому что такой подход создаст шаблоны монстров в будущем.

Или мы можем создать открытый шаблон project.createCircleButton в файле button-circle.soy, вызывать все частные шаблоны из project.createButton в нем, и когда нам нужно "переопределить" один из этих приватных шаблонов (например, project.createCSSClasses_), мы просто создаем новый частный шаблон в button-circle.soy с именем project.createCSSClassesCirbleButton_.

Однако в этом случае нам нужно скопировать все содержимое с project.createButton на project.createCircleButton. Это ужасно.

Также мы попытались использовать шаблоны делегирования, но это не подходит для наследования.

Что такое подход к этой проблеме?

Ответ 1

Мы просто пишем препроцессор, добавляющий @extends к сое.

Ответ 2

Трудно собрать ваш конкретный пример использования, но, широко используя соевое/закрытие в мое время в Google, я сочувствую твоему озадачиванию, поскольку они не мои любимые. Я согласен с общим предложением @Francois-Richard о том, чтобы поддерживать общие шаблоны очень маленькими и составлять несколько вместе. Модель сои (и многие другие системы шаблонов JS, которые я использовал откровенно), сильно предпочитают композицию над наследованием.

Extension

Если a CircleButton логически и стилистически одинаково, но с добавленной функциональностью или стилем, композиция будет работать отлично.

<div class="circle">
  {call .button}
</div>

Параметрирование

Если a CircleButton логически одинаково, но стилистически отличается, почему бы не разрешить параметрирование Button по форме и повторное использование одного и того же шаблона?

{call .button shape="circle" /}

Состав

Если a CircleButton не является ни логически, ни стилистически одинаковым, а просто разделяет некоторые базовые элементы, затем извлекайте их для шаблонов/классов и используйте композицию.

<div class="circle">
  {call .buttonSharedA /}
  <span>{call .buttonSharedB /}</span>
</div>

Соя действительно не преуспевает, а остальная часть закрывается по отношению к OO-мышлению IMHO и просто требует другого подхода.

Ответ 3

Я бы выделил все общие функции/элементы шаблона и создал шаблоны с помощью модуля factory. Каждый шаблон будет представлять собой несколько небольших элементов и функций.