Mục Lục
- Giới thiệu
- Nhắc nhở
- Thêm logic cho trường
- Thêm xác thực cho biểu mẫu
- Hàm validate và error
- Kết hợp schemas
- Kết luận
- Câu hỏi thường gặp
Giới thiệu
Trong bài viết trước, chúng ta đã khám phá cách tạo một biểu mẫu dựa hoàn toàn vào signals. Tuy nhiên, đó là một biểu mẫu đơn giản mà không có logic kinh doanh và quan trọng nhất là không có xác thực.
Bài viết này sẽ chi tiết cách viết logic kinh doanh một cách đơn giản và có khả năng mở rộng.
Nhắc nhở
Một lần nữa, biểu mẫu mà chúng ta đã tạo như sau:
typescript
interface Assigned {
name: string;
firstname: string;
}
interface Todo {
title: string;
description: string;
status: TodoStatus;
assigned: Assigned[];
}
@Component({
selector: 'app-form',
templateUrl: './app-form.html',
imports: [Control]
})
export class AppForm {
todoModel = signal<Todo>({
title: '',
description: '',
status: 'not_begin',
assigned: []
});
todoForm = form(this.todoModel);
}
Như đã chỉ ra trong bài viết trước, một phiên bản FieldState sẽ cung cấp một signal (và do đó là trạng thái phản ứng) như valid hoặc disabled. Tuy nhiên, trạng thái này không được định nghĩa trực tiếp mà thực sự là một trạng thái được tính toán (technically, đó là một computed). Trạng thái này đến trực tiếp từ phần logic của trường trong biểu mẫu.
Thêm logic cho trường
Một trong những khía cạnh chính của biểu mẫu dựa trên signals trong Angular là định nghĩa logic kinh doanh và xác thực. Định nghĩa này được thực hiện một cách tuyên bố trong TypeScript khi biểu mẫu được định nghĩa. Điều này bao hàm hai điều quan trọng:
- Không có lệnh mệnh lệnh để thay đổi trạng thái của một trường sau này; nói cách khác, không có các phương thức như
disable. - Một trường có thể yêu cầu hoặc bị vô hiệu hóa dựa trên các signals khác hoặc các điều kiện tĩnh.
Về cơ bản, logic kinh doanh và xác thực được đại diện bởi một schema. Một schema có thể được coi là một bản thiết kế chứa tất cả các quy tắc kinh doanh của chúng ta cho:
- Toàn bộ biểu mẫu
- Một
Fieldcụ thể
Schema được định nghĩa bằng cách sử dụng hàm schema(). Hàm này được kiểu hóa tổng quát và nhận:
- Giao diện
FieldPathnhư một loại tổng quát. - Một hàm nhận
FieldPathlàm đầu vào và xác định logic kinh doanh của nó.
Kiểu và định nghĩa quy tắc có liên quan chặt chẽ với nhau. Sự liên kết này đảm bảo rằng logic của trường hoàn toàn phù hợp với cấu trúc của biểu mẫu.
Một Schema có thể được tạo bằng cách gọi schema() và truyền cho nó một hàm schema, hoặc chỉ cần truyền một hàm schema trực tiếp cho form() hoặc các phương thức khác mong đợi một Schema.
Sau khi bạn định nghĩa một schema, bạn liên kết nó với cấu trúc Field của mình bằng cách truyền nó như một tham số thứ hai cho hàm form().
Ví dụ về mã
typescript
interface Assigned {
name: string;
firstname: string;
}
interface Todo {
title: string;
description: string;
status: TodoStatus;
assigned: Assigned[];
}
export const TodoSchema = schema<Todo>(path => {});
@Component({
selector: 'app-form',
templateUrl: './app-form.html',
imports: [Control]
})
export class AppForm {
todoModel = signal<Todo>({
title: '',
description: '',
status: 'not_begin',
assigned: []
});
todoForm = form(this.todoModel, TodoSchema);
}
Hiện tại, schema của chúng ta không làm gì cả. Hãy xem cách chúng ta có thể thêm một số chức năng vào nó.
Thêm xác thực cho biểu mẫu
Giống như với Reactive Forms, có các xác thực tích hợp sẵn. Bạn sẽ tìm thấy các loại xác thực cổ điển:
- yêu cầu
Để có danh sách đầy đủ các bộ xác thực hiện có, hãy truy cập đây.
Hãy thêm một số xác thực vào biểu mẫu của chúng ta.
typescript
export const TodoSchema = schema<Todo>(path => {
required(path.title);
required(path.description);
minLength(path.description, 10);
});
Nếu bạn muốn sử dụng logic xác thực của riêng mình thay vì các bộ xác thực tích hợp, hai hàm mới có sẵn cho chúng ta:
- validate
- error
Hàm validate
Hàm validate được sử dụng để thêm xác thực tùy chỉnh cho một trường. Một trường duy nhất có thể có nhiều quy tắc xác thực, và tất cả lỗi quy tắc xác thực có thể được tìm thấy trong FieldState.
Ví dụ:
typescript
const emailSchema = schema<string>(path => {
validate(path, (value) => {
const email = value();
const sfeirPattern = /^\w+\.\w@sfeir.com$/;
return sfeirPattern.test(email) ?
[] : [{ kind: 'sfeir-mail-incorrect', message: 'Required format: x.x@sfeir.com'}]
});
})
Hàm này có thể mạnh mẽ hơn nhiều so với một bộ xác thực email đơn giản. Bởi vì hàm nhận một FieldPath làm tham số đầu tiên, nó có thể xác thực một trường đơn lẻ nhưng cũng có thể xác thực toàn bộ biểu mẫu. Đối với những người yêu thích Zod, việc kết nối xác thực của biểu mẫu với xác thực của Zod trở nên rất dễ dàng.
Hàm error
Hàm error là một phiên bản đơn giản hơn của hàm validate do kiểu trả về của nó. Khác với hàm validate, hàm error trả về một boolean, tùy chọn với một thông điệp được định dạng đúng cho trải nghiệm người dùng.
- true nếu xác thực thành công
- false nếu xác thực thất bại
typescript
const emailSchema = schema<string>(path => {
error(path, (value) => {
const email = value();
const sfeirPattern = /^\w+\.\w@sfeir.com$/;
return sfeirPattern.test(email)
}, 'Required format: x.x@sfeir.com');
})
Kết hợp schemas
Như các ví dụ trên cho thấy, xác thực với signals form rất mạnh mẽ, nhưng có thể trở nên khá dài dòng và nhanh chóng làm phức tạp biểu mẫu của chúng ta. Đây là lúc sự kết hợp và linh hoạt của schemas trở nên rất hữu ích.
Ví dụ:
typescript
export const TodoSchema = schema<Todo>(path => {
required(path.title);
required(path.description);
minLength(path.description, 10);
maxLength(path.description, 150);
});
Mô hình kết hợp cho phép bạn phân tách xác thực biểu mẫu thành các schemas nhỏ hơn, chia sẻ các schemas tổng quát trên toàn ứng dụng của bạn, hoặc thậm chí tốt hơn, trên nhiều ứng dụng nếu chúng ta tạo một thư viện schema.
typescript
const descriptionSchema = schema<string>(path => {
required(path);
minLength(path.description, 10);
maxLength(path.description, 150);
});
export const TodoSchema = schema<Todo>(path => {
required(path.title);
apply(path.description, descriptionSchema);
});
Kết luận
Logic kinh doanh của một biểu mẫu được định nghĩa bằng cách sử dụng một schema, có thể được coi là một bản thiết kế. Gói signal form cung cấp nhiều công cụ hỗ trợ, bao gồm các bộ xác thực tích hợp và các công cụ cho phép sử dụng mẫu kết hợp trong các biểu mẫu.
Điều mà trước đây yêu cầu nhiều mã và suy nghĩ sâu sắc về cấu trúc biểu mẫu giờ đây có thể được thực hiện chỉ với một vài dòng mã đơn giản.
Câu hỏi thường gặp
1. Angular Signals Form là gì?
Angular Signals Form là một cách tiếp cận mới để xây dựng biểu mẫu trong Angular, sử dụng signals để quản lý trạng thái biểu mẫu.
2. Có bao nhiêu loại xác thực có sẵn trong Angular Signals Form?
Có nhiều loại xác thực, bao gồm yêu cầu, email, và xác thực tùy chỉnh có thể được thêm vào.
3. Làm thế nào để thêm logic tùy chỉnh vào biểu mẫu?
Bạn có thể sử dụng các hàm validate và error để thêm logic xác thực tùy chỉnh cho các trường trong biểu mẫu của mình.
4. Có thể tái sử dụng schema không?
Có, bạn có thể xuất schema và sử dụng lại chúng trong nhiều ứng dụng khác nhau.
Lời khuyên và lưu ý quan trọng
- Luôn kiểm tra kỹ lưỡng logic xác thực của bạn để đảm bảo người dùng nhận được trải nghiệm tốt nhất.
- Sử dụng các bộ xác thực tích hợp sẵn khi có thể để giảm thiểu mã cần thiết.
- Tổ chức và cấu trúc schema của bạn một cách hợp lý để dễ dàng bảo trì và mở rộng trong tương lai.