mirror of
https://github.com/a-h/templ.git
synced 2025-02-06 09:45:21 +00:00
refactor: add neater support for code components into templ.Once (#755)
This commit is contained in:
parent
30091610f5
commit
3d154ff737
25
once.go
25
once.go
@ -9,12 +9,27 @@ import (
|
||||
// onceHandleIndex is used to identify unique once handles in a program run.
|
||||
var onceHandleIndex int64
|
||||
|
||||
type OnceOpt func(*OnceHandle)
|
||||
|
||||
// WithOnceComponent sets the component to be rendered once per context.
|
||||
// This can be used instead of setting the children of the `Once` method,
|
||||
// for example, if creating a code component outside of a templ HTML template.
|
||||
func WithComponent(c Component) OnceOpt {
|
||||
return func(o *OnceHandle) {
|
||||
o.c = c
|
||||
}
|
||||
}
|
||||
|
||||
// NewOnceHandle creates a OnceHandle used to ensure that the children of its
|
||||
// `Once` method are only rendered once per context.
|
||||
func NewOnceHandle() *OnceHandle {
|
||||
return &OnceHandle{
|
||||
func NewOnceHandle(opts ...OnceOpt) *OnceHandle {
|
||||
oh := &OnceHandle{
|
||||
id: atomic.AddInt64(&onceHandleIndex, 1),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(oh)
|
||||
}
|
||||
return oh
|
||||
}
|
||||
|
||||
// OnceHandle is used to ensure that the children of its `Once` method are are only
|
||||
@ -28,6 +43,9 @@ type OnceHandle struct {
|
||||
//
|
||||
// https://go.dev/ref/spec#Size_and_alignment_guarantees
|
||||
id int64
|
||||
// c is the component to be rendered once per context.
|
||||
// if c is nil, the children of the `Once` method are rendered.
|
||||
c Component
|
||||
}
|
||||
|
||||
// Once returns a component that renders its children once per context.
|
||||
@ -38,6 +56,9 @@ func (o *OnceHandle) Once() Component {
|
||||
return nil
|
||||
}
|
||||
v.setHasBeenRendered(o)
|
||||
if o.c != nil {
|
||||
return o.c.Render(ctx, w)
|
||||
}
|
||||
return GetChildren(ctx).Render(ctx, w)
|
||||
})
|
||||
}
|
||||
|
11
once_test.go
11
once_test.go
@ -103,4 +103,15 @@ func TestOnceHandle(t *testing.T) {
|
||||
t.Errorf("unexpected diff:\n%v", diff)
|
||||
}
|
||||
})
|
||||
t.Run("a handle can be used to render a specific component", func(t *testing.T) {
|
||||
ctx := templ.WithChildren(context.Background(), templ.Raw("child"))
|
||||
o := templ.NewOnceHandle(templ.WithComponent(templ.Raw("c"))).Once()
|
||||
var w strings.Builder
|
||||
if err := o.Render(ctx, &w); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff("c", w.String()); diff != "" {
|
||||
t.Errorf("unexpected diff:\n%v", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user