You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何将列表型TextEditingController输入存入SQLite?

解决列表型TextEditingController的输入值获取与SQLite存储问题

一、获取列表控制器的所有输入值

列表中的每个元素都是TextEditingController实例,直接遍历列表,逐个取出.text属性就能得到所有输入值。为了避免存入无效的空字符串,建议同时做去空格和非空过滤:

// 获取单个控制器的输入值
final title = titleController.text.trim();
final instructions = _instructionsController.text.trim();
final time = _timeController.text.trim();
final portion = _portionController.text.trim();

// 获取列表控制器的所有输入值(过滤空内容)
final ingredients = _ingredientsController
    .map((controller) => controller.text.trim())
    .where((text) => text.isNotEmpty)
    .toList();

final steps = stepsController
    .map((controller) => controller.text.trim())
    .where((text) => text.isNotEmpty)
    .toList();

final quantities = _quaController
    .map((controller) => controller.text.trim())
    .where((text) => text.isNotEmpty)
    .toList();

二、存入SQLite的两种方案

方案1:将列表转为JSON字符串存入单个字段(适合简单场景)

如果数据结构不复杂,不需要单独查询食材、步骤等子项,可以把列表转成JSON字符串,存入SQLite的单个字段中:

import 'package:sqflite/sqflite.dart';
import 'dart:convert';

Future<void> insertRecipe() async {
  // 打开或创建数据库
  final db = await openDatabase('recipes.db');

  // 将列表转为JSON字符串
  final ingredientsJson = jsonEncode(ingredients);
  final stepsJson = jsonEncode(steps);
  final quantitiesJson = jsonEncode(quantities);

  // 插入主表
  await db.insert(
    'recipes',
    {
      'title': title,
      'instructions': instructions,
      'time': time,
      'portion': portion,
      'ingredients': ingredientsJson,
      'steps': stepsJson,
      'quantities': quantitiesJson,
    },
    conflictAlgorithm: ConflictAlgorithm.replace,
  );
}

方案2:使用关联表(规范的数据库设计,适合复杂查询)

如果需要单独查询食材、步骤等数据,建议使用主表+子表的关联结构,通过外键关联主表ID:

1. 创建关联表

Future<void> createTables(Database db) async {
  // 主表:存储菜谱基本信息
  await db.execute('''
    CREATE TABLE recipes(
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      title TEXT NOT NULL,
      instructions TEXT,
      time TEXT,
      portion TEXT
    )
  ''');

  // 子表:存储食材信息,通过recipe_id关联主表
  await db.execute('''
    CREATE TABLE ingredients(
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      recipe_id INTEGER NOT NULL,
      name TEXT NOT NULL,
      quantity TEXT,
      FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE
    )
  ''');

  // 子表:存储步骤信息,通过recipe_id关联主表
  await db.execute('''
    CREATE TABLE steps(
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      recipe_id INTEGER NOT NULL,
      content TEXT NOT NULL,
      FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE
    )
  ''');
}

2. 插入关联数据(使用事务保证一致性)

Future<void> insertRecipeWithRelations() async {
  final db = await openDatabase('recipes.db');

  // 开启事务,确保主表和子表数据同时插入成功或失败
  await db.transaction((txn) async {
    // 插入主表,返回生成的菜谱ID
    final recipeId = await txn.insert(
      'recipes',
      {
        'title': title,
        'instructions': instructions,
        'time': time,
        'portion': portion,
      },
    );

    // 批量插入食材数据(假设ingredients和quantities是一一对应的)
    for (int i = 0; i < ingredients.length; i++) {
      await txn.insert(
        'ingredients',
        {
          'recipe_id': recipeId,
          'name': ingredients[i],
          'quantity': quantities[i],
        },
      );
    }

    // 批量插入步骤数据
    for (final stepContent in steps) {
      await txn.insert(
        'steps',
        {
          'recipe_id': recipeId,
          'content': stepContent,
        },
      );
    }
  });
}

三、关键注意事项

动态创建的TextEditingController列表必须在组件销毁时逐个释放,避免内存泄漏:

@override
void dispose() {
  // 释放单个控制器
  titleController.dispose();
  _instructionsController.dispose();
  _timeController.dispose();
  _portionController.dispose();

  // 遍历释放列表中的所有控制器
  for (final controller in _ingredientsController) {
    controller.dispose();
  }
  for (final controller in stepsController) {
    controller.dispose();
  }
  for (final controller in _quaController) {
    controller.dispose();
  }

  super.dispose();
}

内容的提问来源于stack exchange,提问作者Edgar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:43:21