Chuyển đến nội dung chính

Bài đăng

Hiển thị các bài đăng có nhãn Forms

Form validation that users finish — hướng dẫn Flutter

Validation should guide, not ambush at submit. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Field-level UX, async validators, and keyboard actions. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Validate on blur for expensive checks; on submit for the rest. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không tr...

Form validation that users finish

Validation should guide, not ambush at submit. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Field-level UX, async validators, and keyboard actions. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Validate on blur for expensive checks; on submit for the rest. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and call...

Form validation that users finish — hướng dẫn Flutter

Validation should guide, not ambush at submit. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Field-level UX, async validators, and keyboard actions. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Validate on blur for expensive checks; on submit for the rest. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không tr...

Form trong Flutter vượt khỏi ví dụ mẫu: validate bất đồng bộ, focus và autofill

Bài cookbook về form của Flutter đưa bạn tới một màn hình đăng ký chạy được trong khoảng bốn mươi dòng. Rồi một designer nhìn vào, và bạn phát hiện lỗi hiện đỏ trước khi ai kịp gõ chữ nào, phím Enter chẳng làm gì, trình quản lý mật khẩu phớt lờ các ô, và trên điện thoại nhỏ thì bàn phím che mất đúng ô bạn đang sửa. Không cái nào trong đó là vấn đề validate. Chúng là những phần của “một form” mà bài hướng dẫn không mô hình hóa. Ba đối tượng, và mỗi cái sở hữu gì Form là một bộ điều phối, không phải một layout. Nó giữ một FormState có thể validate() , save() và reset() mọi FormField nằm bên dưới nó trong cây. FormField sở hữu một giá trị, chuỗi lỗi của nó, và việc nó đã bị chạm tới hay chưa. TextFormField là một FormField bọc quanh một TextField . final _formKey = GlobalKey < FormState >(); Form ( key : _formKey, child : Column (children : [ TextFormField ( decoration : const InputDecoration (labelText : 'Email' ), validator : ...

Form validation that users finish

Validation should guide, not ambush at submit. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Field-level UX, async validators, and keyboard actions. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Validate on blur for expensive checks; on submit for the rest. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and call...

Form trong Flutter vượt khỏi ví dụ mẫu: validate bất đồng bộ, focus và autofill

Bài cookbook về form của Flutter đưa bạn tới một màn hình đăng ký chạy được trong khoảng bốn mươi dòng. Rồi một designer nhìn vào, và bạn phát hiện lỗi hiện đỏ trước khi ai kịp gõ chữ nào, phím Enter chẳng làm gì, trình quản lý mật khẩu phớt lờ các ô, và trên điện thoại nhỏ thì bàn phím che mất đúng ô bạn đang sửa. Không cái nào trong đó là vấn đề validate. Chúng là những phần của “một form” mà bài hướng dẫn không mô hình hóa. Ba đối tượng, và mỗi cái sở hữu gì Form là một bộ điều phối, không phải một layout. Nó giữ một FormState có thể validate() , save() và reset() mọi FormField nằm bên dưới nó trong cây. FormField sở hữu một giá trị, chuỗi lỗi của nó, và việc nó đã bị chạm tới hay chưa. TextFormField là một FormField bọc quanh một TextField . final _formKey = GlobalKey < FormState >(); Form ( key : _formKey, child : Column (children : [ TextFormField ( decoration : const InputDecoration (labelText : 'Email' ), validator : ...

Flutter forms past the toy example: async validation, focus, and autofill

The Flutter form cookbook gets you to a working sign-up screen in about forty lines. Then a designer looks at it and you discover that the errors flash before anyone has typed, the Enter key does nothing, the password manager ignores the fields, and on a small phone the keyboard covers the field you are editing. None of those are validation problems. They are the parts of “a form” that the tutorial does not model. The three objects, and what each owns Form is a coordinator, not a layout. It holds a FormState that can validate() , save() and reset() every FormField beneath it in the tree. FormField owns one value, its error string, and whether it has been touched. TextFormField is a FormField wrapped around a TextField . final _formKey = GlobalKey < FormState >(); Form ( key : _formKey, child : Column (children : [ TextFormField ( decoration : const InputDecoration (labelText : 'Email' ), validator : (value) => (...

Flutter forms past the toy example: async validation, focus, and autofill

The Flutter form cookbook gets you to a working sign-up screen in about forty lines. Then a designer looks at it and you discover that the errors flash before anyone has typed, the Enter key does nothing, the password manager ignores the fields, and on a small phone the keyboard covers the field you are editing. None of those are validation problems. They are the parts of “a form” that the tutorial does not model. The three objects, and what each owns Form is a coordinator, not a layout. It holds a FormState that can validate() , save() and reset() every FormField beneath it in the tree. FormField owns one value, its error string, and whether it has been touched. TextFormField is a FormField wrapped around a TextField . final _formKey = GlobalKey < FormState >(); Form ( key : _formKey, child : Column (children : [ TextFormField ( decoration : const InputDecoration (labelText : 'Email' ), validator : (value) => (...