Overview

Datasource

wuic-data-source e il componente che gestisce metadata, fetch dati, stato corrente, tracking modifiche e sync CRUD.

Descrizione

  • Risolve la route (route/hardcodedRoute o routing URL).
  • Carica metadata tabella/colonne e pubblica stato su fetchInfo$.
  • Gestisce filterInfo, sortInfo, groupInfo, paging (pageSize, currentPage) e cursor paging.
  • Espone metodi runtime per insert/update/delete, batch save, rollback e export.
  • E il punto centrale a cui si agganciano wuic-data-repeater, wuic-filter-bar e wuic-pager.

API

Selector:

  • wuic-data-source

Input principali:

  • route: BehaviorSubject<string>
  • routeFromRouting: boolean
  • hardcodedRoute: string
  • autoload?: boolean
  • loading: BehaviorSubject<boolean>
  • changeTracking?: boolean
  • parentRecord: any
  • parentMetaInfo: MetaInfo
  • parentDatasource: DataSourceComponent
  • componentRef: BehaviorSubject<{ component, id, name, uniqueName }>

Stato/runtime principale:

  • metaInfo: MetaInfo
  • resultInfo: ResultInfo
  • filterInfo?: FilterInfo
  • sortInfo: SortInfo[]
  • groupInfo: GroupInfo[]
  • aggregationInfo: AggregationInfo[]
  • fetchInfo$: BehaviorSubject<{ resultInfo, metaInfo, filterDescriptor }>
  • datasourceReady$: BehaviorSubject<DataSourceComponent | null>
  • afterFirstLoad$: BehaviorSubject<any>
  • beforeSync$: Subject<DataSourceBeforeSyncEvent> (cancellabile)
  • afterSync$: Subject<DataSourceAfterSyncEvent>

Metodi runtime piu usati:

  • fetchData()
  • syncData(entita, original, deleting?, cloning?)
  • addNewRecord(record?)
  • setCurrent(data)
  • clearColumnFilter(col, fetch?)
  • getPendingChanges()
  • hasPendingChanges()
  • batchSave(targetChanges?)
  • rollbackChanges(targetChanges?)
  • exportXls()

Subscriptions/eventi runtime:

  • fetchInfo$: stream principale stato dati/metadati.
  • datasourceReady$: emesso quando l'istanza datasource e pronta.
  • afterFirstLoad$: emesso una sola volta al primo payload utile.
  • beforeSync$: emesso prima di insert/update/delete/clone/batch; puoi annullare con event.cancelSync(...).
  • afterSync$: emesso dopo sync riuscita.

Nota compatibilita:

  • e disponibile anche alias fetchInfo (getter/setter), ma il naming consigliato e fetchInfo$.

Esempi

Esempio base (route hardcoded + autoload)

Snippet 1HTML
<wuic-data-source
  [hardcodedRoute]="'cities'"
  [autoload]="true">
</wuic-data-source>

Esempio master-detail (nested datasource)

Snippet 2HTML
<wuic-data-source #masterDs [hardcodedRoute]="'orders'" [autoload]="true"></wuic-data-source>

<wuic-data-source
  [hardcodedRoute]="'order_rows'"
  [parentDatasource]="masterDs"
  [parentRecord]="masterDs.resultInfo?.current"
  [parentMetaInfo]="masterDs.metaInfo"

Esempio operativo (fetch manuale + sync)

Snippet 3ts
await datasource.fetchData();

const row = datasource.addNewRecord({ customer_name: 'ACME' });
await datasource.syncData(row, null, false, false);

Esempio subscriptions (host)

Snippet 4ts
const subs = new Subscription();

subs.add(
  datasource.fetchInfo$.subscribe((info) => {
    if (!info) return;
    console.log('records', info.resultInfo?.dato?.length || 0);
  })

Patch runtime di metaInfo via fetchInfo$.subscribe

Per modificare runtime i metadati di un nested datasource (es. mc_hide_in_list, md_inline_cell_editing, md_pageable=false, mc_logic_editable=false) senza toccare il DB — patch locale al riferimento cached dal MetadataProviderService, latest-wins, single-dialog scenario — sottoscrivi a fetchInfo$ del data-source:

Snippet 5ts
private bindNestedMetaPatches(): void {
  if (!this.scadenzeDs) return;
  const ESSENTIAL = new Set(['data_scadenza', 'importo', 'pagamento_id', 'stato', 'note']);
  const sub = this.scadenzeDs.fetchInfo$.subscribe((info) => {
    const route = this.scadenzeDs?.route?.value;
    if (!info || route !== info.metaInfo?.tableMetadata?.md_route_name) return;
    const cols: any[] = info.metaInfo?.columnMetadata || [];

Scope:

  • session-only + istanza-only: la patch sopravvive solo finche' il MetadataProviderService cache non viene invalidata o il componente non e' distrutto.
  • utile quando un custom-form vuole una rappresentazione diversa di una nested grid rispetto al rendering standalone (es. nascondere colonne ridondanti in dialog).

Quando NON usare patch runtime:

  • Per modifiche destinate a tutte le istanze della route (anche standalone <route>/list) → patch SQL diretta sui metadati (vedi skill metadata-tables-columns).
  • Per modifiche persistenti tra restart → SQL diretto sui metadati.

Multipli <wuic-data-source> nello stesso componente

Quando un componente custom contiene piu' di un <wuic-data-source> (es. master + nested righe + nested scadenze), il pattern `@ViewChild(DataSourceComponent)` by-type matcha solo il primo data-source nell'ordine top-down del template. Per i successivi serve template reference variable + @ViewChild('refName'):

Snippet 6HTML
<!-- TEMPLATE -->
<wuic-data-source #righeDs   [hardcodedRoute]="'fatture_inviate_righe'" [parentRecord]="record"></wuic-data-source>
<wuic-data-source #scadenzeDs [hardcodedRoute]="'scadenze'"             [parentRecord]="record"></wuic-data-source>
Snippet 7ts
// COMPONENT
import { DataSourceComponent } from 'wuic-framework-lib';

// Primo data-source (matcha by type) -> niente template ref necessario
@ViewChild(DataSourceComponent) righeDs?: DataSourceComponent;

// Secondo data-source -> serve `#scadenzeDs` nel template + by-name ViewChild

Antipattern: document.querySelectorAll('wuic-data-source') + window.ng.getComponent(el) per filtrare per hardcodedRoute. Funziona ma e' fragile, dipende dalla debug API window.ng (non garantita in produzione). Usa sempre template ref.