Skip to main content

build-angular-lists-and-forms

Build ABP Angular list and form pages the framework way — server-side paged/sorted/filtered lists via ListService, and reactive forms with ABP's automatic validation. USE FOR: ListService with component-scoped providers, hookToQuery returning PagedResultDto, get() refresh, page/maxResultCount/filter/sortKey/sortOrder setters, requestStatus$ (isLoading$ is deprecated), totalCount, LIST_QUERY_DEBOUNCE_TIME, reactive forms validated automatically by @ngx-validate/core, DEFAULT_VALIDATION_BLUEPRINTS + withValidationBluePrint localization keys, abp-validation-error, the skipValidation opt-out, and config-driven abp-dynamic-form (DynamicFormComponent + FormFieldConfig). DO NOT USE FOR: proxy consumption, menus, permission directives (angular-ui); proxy generation/regeneration (abp-cli-commands); adding entity/table/toolbar/form-prop extensions to a shipped module (extend-angular-module-ui); component testing (test-angular-ui); server-side application-service or DTO design (build-crud-application-services).

معلومات المصدر

المستودع
abpframework/abp-skills
آخر نشاط في المصدر
٢٠ يوليو ٢٠٢٦ في ٠٣:٢٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٢١
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
build-angular-lists-and-forms
description
Build ABP Angular list and form pages the framework way — server-side paged/sorted/filtered lists via ListService, and reactive forms with ABP's automatic validation. USE FOR: ListService with component-scoped providers, hookToQuery returning PagedResultDto, get() refresh, page/maxResultCount/filter/sortKey/sortOrder setters, requestStatus$ (isLoading$ is deprecated), totalCount, LIST_QUERY_DEBOUNCE_TIME, reactive forms validated automatically by @ngx-validate/core, DEFAULT_VALIDATION_BLUEPRINTS + withValidationBluePrint localization keys, abp-validation-error, the skipValidation opt-out, and config-driven abp-dynamic-form (DynamicFormComponent + FormFieldConfig). DO NOT USE FOR: proxy consumption, menus, permission directives (angular-ui); proxy generation/regeneration (abp-cli-commands); adding entity/table/toolbar/form-prop extensions to a shipped module (extend-angular-module-ui); component testing (test-angular-ui); server-side application-service or DTO design (build-crud-application-services).
license
MIT
# Build Angular Lists and Forms (ABP) ABP's Angular UI ships two pieces of infrastructure that AI models routinely re-implement by hand: `ListService` for server-side paged data, and automatic reactive-form validation. Use them instead of hand-rolling paging state or manual error markup. ## When to Use - A list/table page bound to a paged ABP endpoint (`GetListAsync(input)` returning `PagedResultDto<T>`). - Server-side paging, sorting, and search whose subscriptions are cleaned up on component destroy (not leaked). - A reactive create/edit form that should show ABP's localized validation messages automatically. - An arbitrary (non-entity) form you want to drive from a config array rather than template markup. ## When Not to Use - **Consuming generated proxies, menu routes, permission directives** — use **angular-ui**. - **Generating/regenerating the proxies** (`abp generate-proxy -t ng` or the NX generator) — use **abp-cli-commands**. - **Adding columns/actions/form fields to a *shipped* module's page** (Identity, etc.) — use **extend-angular-module-ui**; that's the extension system, a different API. - **Testing these components** — use **test-angular-ui**. - **Designing the server-side app service / DTOs** — use **build-crud-application-services**. ## Lists with `ListService` `ListService` (from `@abp/ng.core`) owns the query state (page, size, filter, sort) and re-runs the request when any of it changes. It **must be component-scoped** — put it in the component's `providers`, never `providedIn: 'root'` — so its subscriptions are cleaned up on destroy. ```ts import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, inject, OnInit } from '@angular/core'; import { BookService, BookDto } from '../proxy/books'; @Component({ selector: 'app-books', templateUrl: './books.component.html', providers: [ListService], // component-scoped — REQUIRED }) export class BooksComponent implements OnInit { readonly list = inject(ListService); private bookService = inject(BookService); items: BookDto[] = []; count = 0; requestStatus$ = this.list.requestStatus$; // 'idle' | 'loading' | 'success' | 'error' ngOnInit() { // callback receives the composed query, returns Observable<PagedResultDto<T>> this.list .hookToQuery(query => this.bookService.getList(query)) .subscribe(res => { this.items = res.items ?? []; this.count = res.totalCount ?? 0; // read the count off the response }); } } ``` The query object `hookToQuery` passes to your callback is `{ filter, maxResultCount, skipCount, sorting }` — `sorting` is `"field asc|desc"` and `skipCount = page * maxResultCount`, which matches ABP's `PagedAndSortedResultRequestDto`. - **Search:** two-way-bind an input to `list.filter`; the setter re-runs the query. - **Sort:** set `list.sortKey` / `list.sortOrder` (from a table header click). - **Page/size:** set `list.page` / `list.maxResultCount`. - **Refresh after create/update/delete:** call `list.get()` (or `list.getWithoutPageReset()` to stay on the current page). - **Extra query params:** spread the query — `query => this.bookService.getList({ ...query, authorId })`. Debounce is `LIST_QUERY_DEBOUNCE_TIME` (default 300 ms); provide the token alongside `ListService` to change it. ## Reactive forms with automatic validation ABP validates reactive forms through **`@ngx-validate/core`** and renders localized helper text automatically — you do **not** write per-field error `*ngIf` markup. Build a normal `FormGroup` with Angular validators; ABP shows the messages. ```ts form = this.fb.group({ name: ['', [Validators.required, Validators.maxLength(128)]], price: [0, [Validators.required, Validators.min(0)]], }); ``` Message text comes from `DEFAULT_VALIDATION_BLUEPRINTS` (from `@abp/ng.theme.shared`), which maps validator keys (`required`, `email`, `minlength`, …) to localization keys like `AbpValidation::ThisFieldIsRequired`. Override or extend them with `withValidationBluePrint(...)` passed into `provideAbpThemeShared(...)`. - **Custom error rendering:** subclass the `abp-validation-error` component (`ValidationErrorComponent` from `@abp/ng.theme.basic`) and provide `VALIDATION_ERROR_TEMPLATE`. - **Opt out:** put `skipValidation` on a `<form>` (whole form) or on a single `formControlName` input. ## Config-driven dynamic forms For arbitrary (non-entity) forms, drive `<abp-dynamic-form>` (`DynamicFormComponent` from `@abp/ng.components/dynamic-form`) with a `FormFieldConfig[]` array — field types, validators, conditional visibility, nested groups/arrays — instead of writing template markup. This is a **separate validation path** from the reactive-form `@ngx-validate/core` story above: `abp-dynamic-form` does **not** read the theme-shared validation blueprints. It validates from each field's `FormFieldConfig.validators` and renders its own error text (per-field `message`, with an English fallback), so don't expect the automatic localized blueprint messages here — set the message on the field config. ## Validation - Page a list and confirm the network request carries `MaxResultCount`/`SkipCount`/`Sorting` and the grid updates; navigate away and back and confirm no leaked subscriptions (that's the component-scoped provider doing its job). - Submit an invalid form and confirm ABP's localized message appears with **no** hand-written error markup. ## Common Pitfalls - **`ListService` provided in root.** Then it never tears down and leaks across pages. Always component-scoped. - **Reaching for `totalCount$` or `isLoading$`.** `totalCount$` does not exist — read `res.totalCount`. `isLoading$` exists but is **deprecated**; use `requestStatus$`. - **Hand-writing paging state** (page index, skipCount math, debounce). `ListService` already does all of it; wiring your own fights it. - **Manual validation markup.** `@ngx-validate/core` renders messages automatically once the control has Angular validators; adding your own `*ngIf` error blocks duplicates them. - **Confusing the two "dynamic form" APIs.** `abp-dynamic-form` (config-driven, here) is not the entity-extension form (`generateFormFromProps` / `abp-extensible-form`) — that belongs to **extend-angular-module-ui**.
عرض على GitHub