*iterate
Aliases: *iterate, n-iterate Category: placement
Summary
*iterate declares a host-owned placement region. It reads an iterable value, selects a registered *template for each item, and keeps the placed children synchronized without clearing and rebuilding the parent host.
The recommended data shape is an array of objects with a type field:
{
rows: [
{ type: "text", title: "Hello" },
{ type: "image", title: "Photo" }
]
}
With that shape, the short form is enough:
<template *iterate="rows"></template>
<template>
<section *template="'text'">%item.title%</section>
<figure *template="'image'">%item.title%</figure>
</template>
This is read as:
rowsis the iterable source.- each current value is named
item. item.typeselects the*templatename.item.type === "text"uses*template="'text'".
Forms
Short form
<template *iterate="rows"></template>
This is equivalent to:
{ iterable: "rows", variable: "item", template: "item.type" }
Use this when each item is an object and its type field names the template to render.
JavaScript-like form
<template *iterate="row of rows"></template>
This keeps the default template selector based on the chosen variable:
{ iterable: "rows", variable: "row", template: "row.type" }
Object form
Use the object form when the data shape does not use the default names:
<template *iterate="{ iterable: 'rows', variable: 'row', template: 'row.kind' }"></template>
Fields:
iterable: expression or path for the iterable source.variable: local name for the current value. Default:item.template: expression evaluated for each current value. The result is the registered*templatename.
For a constant template, write the template name as the template value:
<template *iterate="{ iterable: 'names', variable: 'name', template: 'name-row' }"></template>
<p *template="'name-row'">%name%</p>
Template Selection
template is evaluated for each item in a scope that includes the parent host data and the current value name.
<template *iterate="{ iterable: 'rows', variable: 'row', template: 'row.kind' }"></template>
<section *template="'note'">%row.title%</section>
<section *template="'task'">%row.title%</section>
If row.kind evaluates to "note", Sercrod renders the template registered as note.
Template sources can be ordinary elements or native template elements:
<section *template="'note'">%item.title%</section>
<template *template="'task'">
<article>%item.title%</article>
</template>
A plain native <template> can be used only to group template declarations in the HTML source:
<template>
<section *template="'text'">%item.title%</section>
<section *template="'image'">%item.title%</section>
</template>
The grouping wrapper is not an iterate warehouse. *iterate still selects the registered *template names directly.
Scope
Normal template elements use the parent host scope plus the current item variable:
<section *template="'text'">%item.title%</section>
A child <serc-rod> without data receives the same local scope for its initial render.
A child <serc-rod data="item"> is handled by the parent placement logic: the parent evaluates item in the local scope, passes that object as the child host data root, and prevents the child from parsing data="item" in the global scope.
<serc-rod *template="'editor'" data="item">
<p>%title%</p>
<button @click="count++">%count%</button>
</serc-rod>
Inside that child host, %title% and %count% refer to the item object.
Staged item editing
A data-less child <serc-rod *stage> inside an iterate template can stage the current object item without making that item the child host's data root:
<serc-rod *template="'editor'" *stage>
<input *input="item.title">
<p>%item.title%</p>
<button type="button" *apply>Apply</button>
<button type="button" *restore>Restore</button>
</serc-rod>
This rule is narrow:
- The child host must have no
dataattribute. *stagemust be empty;*stagevalues are not evaluated as item selectors.- The child must be produced from
*iteratefor an object item. - The current item variable points to the staged item inside the child host.
*applymerges the staged item back into the original item object.*restoreresets only that staged item.- Primitive items such as strings and numbers are not supported for staged item editing and warn.
Use <serc-rod data="item"> when the child should be an independent item-root host. Use data-less <serc-rod *stage> when the child should keep the inherited iterate scope while editing the current object item in a confirmable staged buffer.
Identity And Placement
*iterate is not a faster *for. *for repeats one element from scratch during rendering. *iterate owns a placement region and keeps item-to-DOM records for the current browser run.
Rules:
- Array order is the source of truth.
id,key, and*keysare not used for placement.- The same item object keeps its DOM record when moved.
- A new item object is treated as a new item.
- If the selected template name changes for the same item, the old DOM is removed and a new template is inserted at that position.
- Removed items are cleaned up through the normal Sercrod removal path.
With *dominate
*dominate suppresses the parent host's automatic full redraw, but it does not suppress placement sync. During an automatic update on a dominate host, Sercrod synchronizes registered iterate regions instead of clearing and rebuilding the parent template. The older *dominant spelling remains available as an alias.
This allows large parent hosts to remain stable while item children are added, removed, moved, replaced, or locally updated.
Removed v0.1 placement shape
Sercrod v0.2 removes the older grouped-template placement shape:
{ list: "rows", as: "item", template: "row-tpl", unit: "item.type" }
template no longer names a warehouse, and unit / *unit / *entry are not used for v0.2 *iterate placement. Use iterable, variable, and template instead.
Warnings
Missing template sources, invalid iterate expressions, unsupported legacy place fields, and non-template anchors warn with [Sercrod warn] and continue where possible.