ควบคุมช่องกรอกข้อมูลของคุณด้วย TextEditingController และตรวจสอบทุกช่องพร้อมกันในครั้งเดียว ด้วย Form และ TextFormField
เปิดบทเรียนนี้ใน Kodokonช่องกรอกข้อมูลที่ไม่มีคอนโทรลเลอร์ก็เหมือนกล่องดำ TextEditingController ทำให้คุณเป็นผู้ควบคุม สามารถอ่าน controller.text ได้ทุกเมื่อ เติมค่าให้ช่องล่วงหน้า ล้างค่าหลังส่งข้อมูล หรือฟังทุกการกดแป้นด้วย addListener คอนโทรลเลอร์ถูกสร้างขึ้นใน State ไม่ใช่ใน build เด็ดขาด มิฉะนั้นมันจะถูกสร้างใหม่ทุกครั้งที่มีการรีบิลด์
import 'package:flutter/material.dart';
class NicknameField extends StatefulWidget {
const NicknameField({super.key});
@override
State<NicknameField> createState() =>
_NicknameFieldState();
}
class _NicknameFieldState extends State<NicknameField> {
final _controller = TextEditingController();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: _controller,
decoration: const InputDecoration(
labelText: 'Nickname',
border: OutlineInputBorder(),
),
onSubmitted: (value) => debugPrint(value),
);
}
}ทันทีที่หน้าจอมีหลายฟิลด์ที่ต้องตรวจสอบ ให้ใช้สามสหาย Form, GlobalKey<FormState> และ TextFormField แต่ละฟิลด์จะอธิบายกฎของตัวเองใน validator ฟังก์ชันนี้จะคืนข้อความแสดงข้อผิดพลาด หรือคืน null หากทุกอย่างเรียบร้อยดี การเรียก validate() บนคีย์จะกระตุ้นตัว validator ทั้งหมด พร้อมกันในครั้งเดียว
import 'package:flutter/material.dart';
class SignUpForm extends StatefulWidget {
const SignUpForm({super.key});
@override
State<SignUpForm> createState() => _SignUpFormState();
}
class _SignUpFormState extends State<SignUpForm> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
void _submit() {
if (_formKey.currentState!.validate()) {
debugPrint('Email: ${_emailController.text}');
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required field';
}
if (!value.contains('@')) {
return 'Invalid address';
}
return null;
},
),
const SizedBox(height: 16),
FilledButton(
onPressed: _submit,
child: const Text('Create account'),
),
],
),
);
}
}เมื่อคลิกปุ่ม validate() จะรัน validator แต่ละตัว ข้อความที่คืนกลับมาจะปรากฏเป็นสีแดงใต้ฟิลด์ที่เกี่ยวข้อง และเมท็อดจะคืนค่า false หากมีอย่างน้อยหนึ่งฟิลด์ที่ไม่ถูกต้อง ดังนั้นตรรกะการส่งข้อมูลของคุณจึงอยู่หลัง if เพียงตัวเดียว ทำให้เป็นไปไม่ได้เลยที่จะส่งข้อมูลที่ไม่ถูกต้อง