Întrebările pe care ți le pui de zece ori pe zi, cu răspunsul scurt și link către pagina care o explică pe larg. Caută după un cuvânt sau filtrează pe categorie.
Principiile din spatele tuturor răspunsurilor
- Cât mai aproape de utilizare
Tipuri, componente și stare stau lângă codul care le folosește; le ridici abia când apare un consumator nou.
- O singură sursă de adevăr
Ce se poate calcula se derivă (
computed), nu se stochează. - Unealta cea mai simplă care rezolvă problema
@switchînaintea componentelor dinamice, serviciu cu semnale înaintea NgRx, duplicare înaintea abstracției greșite. - Imutabilitate
Referințe noi pentru date noi — semnalele și OnPush depind de asta.
Întrebări și răspunsuri
41 din 41 întrebări
Componente
7Componenta mea e smart sau dumb?
Dacă injectează store-uri / API / Router → smart (pagină sau container). Dacă primește totul prin input și emite output → dumb. Paginile rutate sunt smart; restul, cât mai multe dumb.
Smart vs DumbCând o fac generică (<T>)?
Când ai deja 2–3 utilizări cu ACELAȘI comportament pe date diferite (tabel, select, listă) și API-ul nu conține termeni de domeniu. Altfel rămâne specifică.
Componente generice <T>Când o fac dinamică?
Doar când nu știi la compilare ce componentă apare (config, CMS, plugin-uri, dashboard). Pentru 2–5 variante cunoscute folosește @switch.
Componente dinamiceinput + output sau model()?
model() pentru valori „de control” (toggle, slider, tab activ). input + output când părintele trebuie să decidă/valideze sau evenimentul are semantică (save, delete).
model() — two-way bindingng-content sau ng-template?
ng-content pentru conținut static afișat o dată. ng-template când conținutul trebuie creat lazy, repetat sau primește date (context).
Content projectionComponentă sau directivă?
Directivă dacă adaugi doar comportament unui element existent (tooltip, autofocus). Componentă dacă ai markup sau stiluri proprii.
Directive & host compositionProiecție sau input-uri pentru conținut?
Input-uri când componenta controlează aspectul (consistență). Proiecție când părintele are nevoie de markup liber (dialoguri, carduri).
Content projectionArhitectură
7Mut componenta în shared?
Doar dacă e folosită ACUM în 2+ feature-uri, nu are termeni de domeniu, nu injectează date și se comportă la fel peste tot. Altfel stă în features/x/ui.
Shared vs featureInterfață inline sau fișier separat?
Folosită de un singur fișier → inline. Tip de input/output → exportat din fișierul componentei. Folosită de mai multe fișiere din feature → features/x/models. Între feature-uri → API public al proprietarului.
Interfețe & modeleFac DTO separat de model?
Da, dacă API-ul are alte convenții, nu e controlat de tine sau UI-ul are câmpuri derivate. Nu, pentru CRUD simplu cu tipuri generate deja „curate”.
Interfețe & modeleCe pun în core?
Lucruri folosite o dată la nivel de aplicație sau infrastructură: auth, layout (shell), ErrorHandler, interceptori, servicii transversale.
Structura de folderePot importa un feature din altul?
Ideal nu. Comunică prin URL, prin un store din core sau prin shared. Dacă e inevitabil: doar prin API-ul public (index.ts) al celuilalt feature.
Barrels, aliasuri & granițeBarrel (index.ts) peste tot?
Nu. Doar la granița unui feature/librării, ca API public. În interior importă fișierele direct.
Barrels, aliasuri & granițeEnum sau union de string-uri?
Union + obiect as const. Mai simplu, tree-shakable, ușor de iterat în template.
Interfețe & modeleStare & date
7signal, computed sau linkedSignal?
signal = stare independentă. computed = derivată, read-only. linkedSignal = derivată, dar editabilă (selecție care se resetează, draft al unui input).
linkedSignal() — stare derivată editabilăCând folosesc effect()?
Doar pentru efecte spre exterior: localStorage, logging, librării imperative, DOM. Niciodată ca să setezi alt semnal (→ computed / linkedSignal).
effect() — când DA, când NUSignal sau Observable?
Signal pentru stare afișată. Observable pentru fluxuri de evenimente în timp (websocket, drag, operatori complecși). Puntea: toSignal / toObservable.
Signals ↔ RxJSCum iau date de la server?
Citire reactivă → httpResource (sau resource / rxResource). Scriere (POST/PUT/DELETE) → HttpClient, apoi update/reload pe resursă.
resource, rxResource, httpResourceUnde țin starea?
Cât mai jos: componentă → store de feature (providers pe rută/pagină) → global (@Service în root). Filtre partajabile → URL.
State management cu signalsAm nevoie de NgRx?
De obicei nu: un serviciu cu semnale ajunge. NgRx SignalStore dacă vrei convenții/plugin-uri; NgRx Store dacă ai nevoie de log de acțiuni și time-travel.
State management cu signalsDebounce pe un semnal?
debounced(sig, 300) (v22, experimental). În Signal Forms: regula debounce() sau opțiunea debounce din validateHttp.
debounced() — semnale cu întârziereTemplate
5Metodă, pipe sau computed în template?
computed pentru calcule specifice componentei; pipe pur pentru formatări refolosite; metodă doar pentru lucruri triviale (rulează la fiecare randare).
Pipes: când și cumCe pun la track în @for?
Un id stabil (track item.id). $index doar pentru liste statice. Identitatea (track item) doar dacă obiectele nu sunt recreate.
Control flow: @if, @for, @switchngClass sau [class]?
[class.x] / [class] — nativ, fără import, mai rapid. Migrare: ng g @angular/core:ngclass-to-class.
Class & style bindingsCând @defer?
Conținut greu sau sub fold (grafice, comentarii, editoare). Nu pentru conținutul principal (LCP).
@defer — lazy loading în templateCât de multă logică în template?
Expresii simple și @let pentru sub-expresii. Reguli de business și calcule pe liste mari → computed.
@let și expresiile noi din templateDI
5@Service() sau @Injectable()?
Cod nou în v22: @Service() (singleton auto-provided, doar inject()). @Injectable dacă ai DI prin constructor sau suport pentru versiuni vechi.
inject() & @Service()Unde furnizez serviciul?
Root dacă starea trebuie să supraviețuiască navigării. Rută/pagină pentru stare de feature. Componentă pentru o instanță per componentă (wizard, editor).
Providers & ierarhia de injectoriClasă sau InjectionToken?
Clasă când ai logică/metode. InjectionToken pentru valori: config, URL-uri, funcții, plugin-uri (multi).
InjectionToken & provideX()Interfață pentru serviciu (IUserService)?
Nu. Dacă ai nevoie de implementări multiple sau mock-uri: clasă abstractă ca token, cu @Service({ factory }) pentru implementarea implicită.
inject() & @Service()Serviciu greu, folosit rar?
injectAsync(() => import(...)) cu prefetch: onIdle (v22).
injectAsync() — servicii lazyFormulare & routing
6Signal Forms sau Reactive Forms?
Formulare noi în v22 → Signal Forms. Cele existente pe Reactive rămân; migrezi treptat cu SignalFormControl / compatForm.
Signal Forms — bazeleControl custom: FormValueControl sau CVA?
FormValueControl pentru Signal Forms (un model() + input-uri opționale). ControlValueAccessor pentru Reactive / template-driven.
Controale custom de formularResolver sau httpResource?
Resolver pentru date mici, obligatorii. httpResource + skeleton pentru liste și dashboard-uri (navigare instant).
Guards & resolverscanMatch sau canActivate?
canMatch pentru zone restricționate (nu descarcă chunk-ul). canActivate pentru verificări la intrare pe o rută care există pentru toți.
Guards & resolversRută separată sau stare în pagină?
Rută dacă ecranul trebuie să aibă link propriu (partajabil, back button). Stare locală pentru dialoguri, dropdown-uri, pași efemeri.
Routing modern & lazy loadingCum citesc parametrii de rută?
withComponentInputBinding() + input() în componenta rutată. Fără ActivatedRoute și subscribe.
Routing modern & lazy loadingCalitate
4De ce nu se actualizează UI-ul?
Aproape sigur: un câmp simplu modificat asincron (setTimeout, subscribe) într-o aplicație zoneless/OnPush, sau un obiect mutat. Treci pe semnale și update-uri imutabile.
Change detectionUnde tratez erorile?
Previzibile → local (resource.error()). Transversale (401/500) → interceptor. Randare a unei zone → @boundary. Restul → ErrorHandler global.
Erori: @boundary & ErrorHandlerCe testez și cum?
Store-uri și mapperi: unitar, fără DOM. Componente dumb: createComponent + bindings. Pagini: store fals + HttpTestingController. Fluxuri: e2e.
Testare cu VitestComponente proprii accesibile?
Construiește-le peste Angular Aria (headless): tastatură, focus și ARIA corecte, stilul e al tău.
Angular Aria