一键导入
angular-conventions
Coding standards, architectural rules, and project-specific conventions for the Angular application.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Coding standards, architectural rules, and project-specific conventions for the Angular application.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Core principles that must be applied to ALL tasks, including mandatory self-documentation and knowledge persistence at the end of workflows.
Tailwind CSS configuration and Angular Material component usage guidelines.
Instructions for interacting with the local Supabase backend.
基于 SOC 职业分类
| name | Angular Conventions |
| description | Coding standards, architectural rules, and project-specific conventions for the Angular application. |
To ensure high-quality, maintainable, and modern code, adhere to the following guidelines. These are non-negotiable for new feature development.
Angular 21 relies heavily on Signals for fine-grained reactivity.
Inputs: Use input() and input.required() instead of @Input().
// DO
readonly userId = input.required<string>();
readonly options = input<Option[]>([])
// DON'T
@Input() userId!: string;
Queries: Use viewChild(), contentChildren(), etc.
// DO
readonly submitBtn = viewChild<ElementRef>('submit');
Outputs: Use output() instead of @Output().
// DO
readonly validated = output<boolean>();
State: Use signal() and computed() for local component state.
readonly count = signal(0);
readonly doubleCount = computed(() => this.count() * 2);
Always use the built-in control flow syntax. It is more readable and performant than *ngIf and *ngFor.
<!-- DO -->
@if (user(); as u) {
<user-card [user]="u" />
} @else {
<login-prompt />
} @for (item of items(); track item.id) {
<list-item [item]="item" />
} @empty {
<li>No items found</li>
}
While Signals are preferred for synchronous state, RxJS is still the standard for asynchronous streams (HTTP, WebSockets).
toSignal to consume Observables in templates synchronously.
readonly users = toSignal(this.userService.getUsers(), { initialValue: [] });
toObservable when you need to switch from a Signal to a Stream (e.g., for debounce).
toObservable(this.searchTerm)
.pipe(debounceTime(300))
.subscribe(...)
.ts), template (.html), and styles (.scss). NEVER use inline template or styles.ChangeDetectionStrategy.OnPush.
@Component({
selector: 'app-feature',
imports: [CommonModule, MatButtonModule],
templateUrl: './feature.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
input(), emits events via output(). No dependency injection of Services.@defer to lazy load non-critical components.
@defer (on viewport) {
<heavy-chart />
} @placeholder {
<loading-spinner />
}
NgOptimizedImage (ngSrc) instead of src.any: explicit types or generalized generics are required.null / undefined explicitly.The app is translated into over 20 languages. NEVER hardcode user-facing text in templates or components, EXCEPT for files within the apps/picsa-apps/dashboard application, which does not require strict translation enforcement.
Templates: Always use the translate pipe.
<!-- DO -->
<button>{{ 'Share' | translate }}</button>
<!-- DON'T -->
<button>Share</button>
This project uses Angular Material 21 with specific design patterns. Standard legacy Angular Material directives (like mat-button) have been superseded or abstracted in this project.
matButton directive with its specific variants (e.g., <button matButton="filled" color="primary">).mat-button, mat-raised-button, etc.matButton as a "duplicate attribute" or "incorrect directive selector". In this architecture, matButton is the strictly correct and expected directive selector.