Update Render component to accept multiple items, closures, and default to rendering it to a component writer.

This commit is contained in:
Jesse Brault 2025-06-01 11:53:30 -05:00
parent 13f85325a1
commit df395da792
3 changed files with 42 additions and 11 deletions

View File

@ -1,26 +1,34 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.View import groowt.view.View
import groowt.view.component.runtime.DefaultComponentWriter
class Render extends DelegatingWebViewComponent { class Render extends DelegatingWebViewComponent {
private final Object item private final Object items
Render(Map attr) { Render(Map attr) {
item = Objects.requireNonNull(attr.item, "<Render> attribute 'item' must not be null.") if (attr.item && attr.items) {
throw new IllegalArgumentException("<Render> cannot have both 'item' and 'items' attributes.")
}
this.items = attr.item ? [attr.item] : attr.items ?: []
} }
@Override @Override
protected View getDelegate() { protected View getDelegate() {
return { Writer w -> return { Writer w ->
if (item.respondsTo('renderTo', [Writer] as Class[])) { items.each {
item.renderTo(w) if (it instanceof Closure) {
} else if (item.respondsTo('render')) { it = it()
w << item.render() }
} else { if (it.respondsTo('renderTo', [Writer] as Class[])) {
throw new IllegalArgumentException( it.renderTo(w)
'<Render> must use an item which responds to either renderTo(Writer) or render().' } else if (it.respondsTo('render')) {
) w << it.render()
} else {
def cw = new DefaultComponentWriter(w, context.renderContext, context)
cw << it
}
} }
} }
} }

View File

@ -1,6 +1,5 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.component.web.WebViewComponentContext import groowt.view.component.web.WebViewComponentContext
import groowt.view.component.web.WebViewComponentScope import groowt.view.component.web.WebViewComponentScope
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test

View File

@ -1,5 +1,7 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.component.web.BaseWebViewComponent
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
class RenderTests extends AbstractWebViewComponentTests { class RenderTests extends AbstractWebViewComponentTests {
@ -20,6 +22,14 @@ class RenderTests extends AbstractWebViewComponentTests {
} }
static final class Hello extends BaseWebViewComponent {
Hello() {
super('Hello, World!')
}
}
@Test @Test
void renderToExample() { void renderToExample() {
doTest(''' doTest('''
@ -44,4 +54,18 @@ class RenderTests extends AbstractWebViewComponentTests {
) )
} }
@Test
void rendersComponent() {
doTest('<Render item={<RenderTests.Hello />} />', 'Hello, World!', context {
configureRootScope {
addWithNoArgConstructor(Hello)
}
})
}
@Test
void rendersItems() {
doTest('<Render items={[0, 1, 2]} />', '012')
}
} }