ניקוי באמצעות finally
חלק מהיחידה נתונים ורשת במסלול ה-Flutter של Coddy. שיעור 12 מתוך 27.
יש פעולות שצריכות להתבצע בין אם קריאה הצליחה ובין אם נכשלה: להסתיר את מחוון הטעינה ולהפעיל מחדש כפתור. קל לשכוח לכתוב אותן באחד משני הבלוקים, try או catch. ל-Dart יש בלוק שלישי בשביל זה, finally:
try {
await saveName(name);
} catch (e) {
// הצג את השגיאה
} finally {
// תמיד מתבצע: אחרי try או אחרי catch
}finally מתבצע אחרון, בכל פעם: אחרי try כשהפעולה הצליחה, ואחרי catch כשהיא נכשלה. כך הוא המקום היחיד לבטל את מה שהגדרת לפני הקריאה.
כאן האפליקציה מאפירה את Save בזמן השמירה, באמצעות onPressed: saving ? null : save. אי אפשר ללחוץ על כפתור שהערך של onPressed שלו הוא null. אם saving לא יחזור לעולם ל-false, הכפתור יישאר אפור לתמיד.
אתגר
בינונישמור כשהשדה ריק: השגיאה מופיעה, והלחצן Save נשאר אפור, כך שאי אפשר לנסות שוב. העבר את saving = false מתוך בלוק ה־try אל בלוק finally, בתוך setState משלו.
נסו בעצמכם
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: NameScreen(),
);
}
}
class NameScreen extends StatefulWidget {
const NameScreen({super.key});
@override
State<NameScreen> createState() => _NameScreenState();
}
class _NameScreenState extends State<NameScreen> {
final controller = TextEditingController();
String status = '';
bool saving = false;
@override
void dispose() {
controller.dispose();
super.dispose();
}
Future<void> saveName(String name) async {
await Future.delayed(const Duration(seconds: 1));
if (name.isEmpty) {
throw Exception('The name cannot be empty');
}
}
Future<void> save() async {
setState(() {
saving = true;
});
try {
await saveName(controller.text);
setState(() {
status = 'Saved: ${controller.text}';
saving = false;
});
} catch (e) {
setState(() {
status = '$e';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Name'),
),
const SizedBox(height: 16),
ElevatedButton(onPressed: saving ? null : save, child: const Text('Save')),
const SizedBox(height: 16),
Text(status, style: const TextStyle(fontSize: 18)),
],
),
),
);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה נתונים ורשת
3כשקריאות נכשלות
תפיסת שגיאות באמצעות tryזריקת שגיאהניקוי באמצעות finallyמצב השגיאה של FutureBuilderכפתור לניסיון חוזרתרגלו בעצמכם: קומפיילר Flutter אונליין