一键导入
angular-forms
Angular forms: Signal Forms (experimental) and Reactive Forms. Trigger: When working with forms, validation, or form state in Angular.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Angular forms: Signal Forms (experimental) and Reactive Forms. Trigger: When working with forms, validation, or form state in Angular.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Lucy-ai's own agent ecosystem installer, updater, and verifier. Use this skill when: - Installing lucy-agent on a new OpenClaw instance - Updating lucy-agent in-place - Verifying the lucy-agent installation - Understanding the lucy-agent structure
Angular architecture: Scope Rule, project structure, file naming, style guide. Trigger: When structuring Angular projects or deciding where to place components.
Angular core patterns: standalone components, signals, inject, control flow, zoneless. Trigger: When creating Angular components, using signals, or setting up zoneless.
Angular performance: NgOptimizedImage, @defer, lazy loading, SSR. Trigger: When optimizing Angular app performance, images, or lazy loading.
OWASP Top 10 2025 security guidance for ZENTICALAB. Broken Access Control, Cryptographic Failures, Injection, and more — mapped to .NET + Angular.
Comprehensive PR review skill for ZENTICALAB projects (.NET backend + Angular frontend). Use when reviewing pull requests, checking code quality, or validating implementations against spec. Loaded automatically when reviewing PRs in ZENTICALAB repos.
| name | angular-forms |
| description | Angular forms: Signal Forms (experimental) and Reactive Forms. Trigger: When working with forms, validation, or form state in Angular. |
| metadata | {"author":"gentleman-programming","version":"1.0"} |
| Use Case | Recommendation |
|---|---|
| New apps with signals | Signal Forms (experimental) |
| Production apps | Reactive Forms |
| Simple forms | Template-driven |
import { form, FormField, required, email } from '@angular/forms/signals';
@Component({
imports: [FormField],
template: `
<!-- inline for docs brevity; use templateUrl in production -->
<form>
<input [formField]="emailField" type="email" />
<input [formField]="passwordField" type="password" />
<button (click)="submit()">Login</button>
</form>
`
})
export class LoginComponent {
readonly loginForm = form({
email: ['', [required, email]],
password: ['', required]
});
readonly emailField = this.loginForm.controls.email;
readonly passwordField = this.loginForm.controls.password;
submit() {
if (this.loginForm.valid()) {
const values = this.loginForm.value();
}
}
}
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
@Component({
imports: [ReactiveFormsModule],
template: `
<!-- inline for docs brevity; use templateUrl in production -->
<form [formGroup]="form" (ngSubmit)="submit()">
<input formControlName="email" type="email" />
<input formControlName="password" type="password" />
<button type="submit" [disabled]="form.invalid">Login</button>
</form>
`
})
export class LoginComponent {
private readonly fb = inject(FormBuilder);
form = this.fb.nonNullable.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]],
});
submit() {
if (this.form.valid) {
const { email, password } = this.form.getRawValue();
}
}
}
fb.nonNullable.group() for type safetygetRawValue() to get typed valuesform = this.fb.nonNullable.group({
name: [''],
address: this.fb.group({
street: [''],
city: [''],
}),
phones: this.fb.array([this.fb.control('')]),
});
get phones() {
return this.form.get('phones') as FormArray;
}
addPhone() {
this.phones.push(this.fb.control(''));
}