Cos’è il Power Apps Component Framework
Il Power Apps Component Framework (PCF) consente di costruire code component riutilizzabili in TypeScript per estendere la UX di model-driven app e canvas app. A differenza di soluzioni no-code, PCF dà pieno controllo su rendering, eventi e chiamate dati, rendendolo la scelta corretta quando il requisito è un controllo interattivo ricco (slider, mappa, griglia custom, star-rating) legato a un campo o a un set di record.
Field component vs dataset component
La prima decisione architetturale è il tipo di componente:
- Field component: si aggancia a un singolo campo (colonna) di un form. Riceve e scrive un unico valore. Ideale per sostituire il controllo predefinito di un attributo (es. un numero reso come slider).
- Dataset component: opera su una collezione di record (una view o una subgrid). Riceve un oggetto
datasetcon record, colonne, paging e sorting. Adatto a visualizzazioni tabellari/kanban/calendari alternative alla griglia standard.
La scelta si riflette direttamente nel manifest e nell’API che il componente riceve nel context.
ControlManifest
Il file ControlManifest.Input.xml è il contratto dichiarativo del componente. Definisce:
- namespace e constructor (identità univoca del controllo);
- i property (per un field component) con
of-type(es.SingleLine.Text,Whole.None) e usagebound/input, oppure un data-set con le sue colonne per un dataset component; - le feature-usage (
<feature-usage>) da abilitare esplicitamente per usare API come WebAPI,Device,Utility; - le resources: bundle
code, file CSS, RESX per la localizzazione, immagini.
Le proprietà bound sono lette/scritte sul record; le input sono di sola configurazione. Dichiarare qui i permessi è obbligatorio: usare context.webAPI senza la relativa feature nel manifest non funziona a runtime.
Il ciclo di vita
Ogni componente implementa l’interfaccia StandardControl con quattro metodi:
init(context, notifyOutputChanged, state, container): chiamato una volta. Qui si crea il DOM iniziale nelcontainer, si salvanotifyOutputChangede si prepara lo stato. Non è ancora garantito che i dati siano definitivi.updateView(context): chiamato ogni volta che qualcosa cambia (valori dei campi bound, dimensioni, dataset ricaricato). È il cuore del rendering: si legge tutto dacontext.parameterse si aggiorna la UI. Il refresh dei dati passa sempre dalcontext, non da fetch arbitrari sganciati dal framework.getOutputs(): restituisce un oggetto con i valori che il componente vuole scrivere sulle proprietà bound. Viene invocato dopo che il codice chiamanotifyOutputChanged(), segnalando alla piattaforma che l’output è cambiato.destroy(): cleanup finale — rimuovere event listener e liberare risorse per evitare memory leak.
Il flusso tipico di scrittura è: l’utente interagisce → il codice aggiorna lo stato interno → chiama notifyOutputChanged() → la piattaforma invoca getOutputs() → il valore risale al form.
Tooling con Power Platform CLI
Il Power Platform CLI (pac) è lo strumento ufficiale:
pac pcf init --namespace Contoso --name Rating --template field
npm install
npm start watch # test harness locale
Per il rilascio, PCF deve essere impacchettato in una solution: non si può importare direttamente il bundle. Il pattern è creare un progetto solution e referenziare il componente:
pac solution init --publisher-name contoso --publisher-prefix con
pac solution add-reference --path ../Rating
dotnet build # produce la managed/unmanaged solution
La solution (managed in produzione) è l’unità di deploy tra ambienti Dataverse.
PCF a confronto
- vs HTML web resource: le web resource sono HTML/JS ospitati come risorse, non tipizzati, senza lifecycle né binding nativo ai campi; PCF offre TypeScript tipizzato, integrazione con il data model, supporto responsive e riuso su più form.
- vs componenti canvas nativi: i controlli canvas standard bastano per scenari semplici; PCF serve quando serve logica/rendering non esprimibile con le proprietà native. PCF gira sia in model-driven sia in canvas (con code components abilitati nell’ambiente).
Trappole tipiche d’esame
- Scenario: il caricamento del componente è lento e pesa sulla pagina → ridurre il bundle size (tree-shaking, evitare librerie enormi, non includere React se già fornito dalla piattaforma). Bundle troppo pesanti sono un anti-pattern penalizzato.
- Scenario: serve rileggere i dati aggiornati di un record → affidarsi al
contextinupdateView(e acontext.webAPIsolo se dichiarato nel manifest), non a fetch esterni scollegati dal framework. - Scenario: distribuire il PCF in un altro ambiente → impacchettarlo in una solution (managed) via
pac solution; il bundle da solo non è deployabile. - Scenario: il valore modificato non torna al form → mancata chiamata a
notifyOutputChanged()ogetOutputs()che non restituisce la proprietà bound. - Scenario: controllo su una subgrid/vista di record → serve un dataset component, non un field component (che gestisce un solo attributo).