Skip to main content
cngx-src documentation

CngxRecyclerRow

DirectivePrimaryv0.1.0WCAG AA

projects/common/data/recycler/recycler-row.directive.ts

Import#

import { CngxRecyclerRow } from '@cngx/common/data'

Description#

Per-window-position render switch for a sparse/windowed recycler: renders the consumer's real-row template when the sliced item is defined, and a placeholder branch when the item is still undefined (loaded window, data not yet resolved).

Mirrors the *cngxAsync structural-directive shape (own TemplateRef + microsyntax alternate template + ngTemplateContextGuard). The switch axis is data availability, not async status, so the two are siblings, not the same class. Unlike *cngxAsync (which clears on every switch) the real-row view is cached and re-attached across a placeholder detour, so a defined -> undefined -> defined flip never remounts the expensive real row.

The placeholder branch resolves through a 3-stage cascade: the microsyntax placeholder: template, then CNGX_RECYCLER_PLACEHOLDER_ROW, then a built-in imperative <li> default. The default assumes a <ul>/<li> list; a non-<li> container (<div role="list">) supplies a placeholder: template or the config token instead.

The two placeholder layers are orthogonal and non-overlapping by construction: CngxRecyclerPlaceholder paints a decorative background on the offset spacers (indices outside the rendered window), while this directive fills holes inside the window whose item is still undefined.

Windowed list with the built-in placeholder row

<ul>
  @for (item of visibleItems(); track item?.id ?? ('ph:' + (recycler.start() + $index)); let i = $index) {
    <li *cngxRecyclerRow="item; index: recycler.start() + i; recycler: recycler; let row">
      {{ row?.name }}
    </li>
  }
</ul>

Custom placeholder template

<ul>
  @for (item of visibleItems(); track item?.id ?? ('ph:' + (recycler.start() + $index)); let i = $index) {
    <li *cngxRecyclerRow="item; index: recycler.start() + i; recycler: recycler; placeholder: ph; let row">
      {{ row?.name }}
    </li>
  }
  <ng-template #ph let-index let-setSize="setSize">
    <li role="listitem" aria-busy="true" [attr.aria-posinset]="index + 1" [attr.aria-setsize]="setSize">
      Loading row {{ index + 1 }}
    </li>
  </ng-template>
</ul>

https://cngxjs.github.io/cngx/examples/#/common/data/recycler/windowed-data-availability

Metadata#

Index#

Inputs#

cngxRecyclerRow#T | undefined
input()

The sliced item at this window position. undefined selects the placeholder branch.

cngxRecyclerRowIndex#number
input()Required

Absolute dataset index of this slot (recycler.start() + $index).

cngxRecyclerRowPlaceholder#TemplateRef | undefined

Optional placeholder template for the undefined branch. Context: CngxRecyclerRowContext.

default undefined,
cngxRecyclerRowRecycler#CngxRecycler
input()Required

The recycler driving the window, read for rowSizeHint (-> top) and ariaSetSize.

Methods#

ngTemplateContextGuard#CngxRecyclerRowRealContext
Static
ngTemplateContextGuard(_dir: CngxRecyclerRow<T>, _ctx: unknown)

Narrows the directive's own template context to the loaded item type.

@param_dirCngxRecyclerRow
@param_ctxunknown