import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; import { Observable, of, timer } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { CommonModule } from '@angular/common'; import { RouterLink } from '@angular/router'; @Component({ selector: 'app-devui-form', standalone: true, imports: [ReactiveFormsModule, CommonModule, RouterLink], template: `
`, styles: [` .container { max-width: 800px; margin: 0 auto; padding: 20px; } .back-link { display: inline-block; margin-bottom: 1rem; color: #007bff; text-decoration: none; } .form-container { background: #f9f9f9; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; font-weight: bold; } .form-control { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; box-sizing: border-box; } .form-control.error { border-color: #dc3545; } .error-message { color: #dc3545; font-size: 14px; margin-top: 5px; } .checkbox-group label { font-weight: normal; display: flex; align-items: center; } .checkbox-group input { width: auto; margin-right: 8px; } .form-actions { display: flex; gap: 10px; margin-top: 20px; } .btn { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } .btn-primary { background-color: #007bff; color: white; } .btn-primary:disabled { background-color: #ccc; cursor: not-allowed; } .btn-secondary { background-color: #6c757d; color: white; } .form-data { margin-top: 30px; padding: 20px; background: #e9ecef; border-radius: 4px; } .form-data pre { background: white; padding: 15px; border-radius: 4px; overflow: auto; } @media (max-width: 768px) { .container { padding: 10px; } .form-container { padding: 15px; } .form-actions { flex-direction: column; } .btn { width: 100%; margin-bottom: 10px; } } `] }) export class DevuiFormComponent implements OnInit { userForm: FormGroup; showAdminFields = false; submittedData: any = null; constructor(private fb: FormBuilder) { this.userForm = this.fb.group({ username: ['', [Validators.required, Validators.minLength(3)]], email: ['', [Validators.required, Validators.email]], age: ['', [Validators.required, Validators.min(18), Validators.max(100)]], department: ['', Validators.required], isAdmin: [false] }); } ngOnInit() { // 监听用户名变化以演示异步验证 this.userForm.get('username')?.valueChanges.subscribe(value => { console.log('Username changed:', value); }); } // 动态添加/删除管理员字段 toggleAdminFields(event: any) { const isChecked = event.target.checked; this.showAdminFields = isChecked; if (isChecked) { this.userForm.addControl('adminCode', this.fb.control('', [Validators.required, Validators.minLength(6)])); } else { this.userForm.removeControl('adminCode'); } } // 异步验证器模拟 uniqueUsernameValidator() { return (control: any) => { if (!control.value) { return of(null); } // 模拟服务端检查用户名是否已存在 const isTaken = control.value.toLowerCase() === 'admin' || control.value.toLowerCase() === 'user' || control.value.toLowerCase() === 'test'; // 模拟网络延迟 return timer(500).pipe( map(() => isTaken ? { usernameTaken: true } : null) ); }; } onSubmit() { if (this.userForm.valid) { this.submittedData = this.userForm.value; console.log('Form submitted:', this.userForm.value); } else { // 标记所有字段为已触碰以显示验证错误 this.markFormGroupTouched(); } } resetForm() { this.userForm.reset({ isAdmin: false }); this.showAdminFields = false; this.submittedData = null; } private markFormGroupTouched() { Object.keys(this.userForm.controls).forEach(key => { const control = this.userForm.get(key); control?.markAsTouched(); }); } }