---
title: Flutter与Back4app集成进行Parse对象CRUD操作指南
slug: docs-ch/flutter/parse-sdk/data-objects/flutter-crud
description: 学习如何在Flutter中通过Back4app执行解析对象的增删改查操作。详细步骤与示例代码。
image: https://www.back4app.com/images/logo-social.png
createdAt: 2024-03-15T13:21:54.274Z
---

本指南演示了如何使用 Flutter 插件在 Back4App 上管理 Parse 对象。您将学习基本的 CRUD 操作：创建、读取、更新和删除。本教程使用一个简单的待办事项应用程序来说明这些操作。

Back4app 后端数据存储围绕着 `ParseObject`, 它保存 JSON 兼容数据的键值对。Back4App 数据存储支持广泛的常见数据类型，包括字符串、数字、布尔值、日期时间、地理点、指针、关系，以及列表和对象。基本上，它支持任何可以编码为 JSON 格式的数据，为各种数据存储需求提供灵活而强大的解决方案。

## 先决条件

要完成本教程，您需要：

:::hint{type="info"}
- Flutter 版本 3.x.x 或更高版本
- [Android Studio ](https://developer.android.com/studio)或 [已安装的 VS Code](https://code.visualstudio.com/)（带有 [插件](https://docs.flutter.dev/get-started/editor) Dart 和 Flutter）
- 一个应用 [创建](https://www.back4app.com/docs/get-started/new-parse-app) 在 Back4App 上:
  - **注意:&#x20;**&#x8BF7;遵循 [新解析应用教程](https://www.back4app.com/docs/get-started/new-parse-app) 以了解如何在 Back4App 上创建解析应用.
- 一个连接到 Back4app 的 Flutter 应用.
  - **注意:&#x20;**&#x8BF7;遵循 [在 Flutter 项目中安装解析 SDK](https://www.back4app.com/docs/flutter/parse-sdk/parse-flutter-sdk) 以创建一个连接到 Back4App 的 Flutter 项目.
- 一台运行 Android 或 iOS 的设备（或虚拟设备）。
:::

## 1. 创建对象

这个 `saveTodo` 函数创建一个新的任务，带有标题和一个 `done` 状态设置为 false。它的工作原理如下：

1. **初始化 Parse 对象并设置其属性**: 创建一个 `ParseObject` 的实例用于你的类（例如，'Todo'）。使用 `set` 方法来定义键值对。
2. **保存对象**: 调用 `save` 方法将对象存储在数据库中。

```dart
Future<void> saveTodo(String title) async {
  final todo = ParseObject('Todo')
    ..set('title', title)
    ..set('done', false);
  await todo.save();
}
```

## 2. 读取对象

这个 `getTodo` 函数查询数据库并返回任务列表。它的工作原理如下：

1. **初始化查询**: 为你的类创建一个 `QueryBuilder` 的实例。
2. **执行查询**: 使用 `query` 方法来检索数据。
3. **处理响应**: 检查查询是否成功并处理结果。

```dart
Future<List<ParseObject>> getTodo() async {
  QueryBuilder<ParseObject> queryTodo =
      QueryBuilder<ParseObject>(ParseObject('Todo'));
  final ParseResponse apiResponse = await queryTodo.query();

  if (apiResponse.success && apiResponse.results != null) {
    return apiResponse.results as List<ParseObject>;
  } else {
    return [];
  }
}
```

更新 `ListView.builder` 函数以提取和显示 Parse 对象值：

```dart
// Get Parse Object Values
final varTodo = snapshot.data![index];
final varTitle = varTodo.get<String>('title')!;
final varDone = varTodo.get<bool>('done')!;
```

## 3. 更新对象

该 `updateTodo` 函数更新现有任务的状态。以下是它的工作原理：

1. **初始化 Parse 对象并设置属性**: 创建一个 `ParseObject` 的实例并设置其 `objectId`. 使用 `set` 方法更新键值对。
2. **保存对象**: 调用 `save` 方法将对象更新到数据库中。

```dart
Future<void> updateTodo(String id, bool done) async {
  var todo = ParseObject('Todo')
    ..objectId = id
    ..set('done', done);
  await todo.save();
}
```

## 4. 删除对象

该 `deleteTodo` 函数从数据库中删除现有任务。以下是它的工作原理：

1. **初始化 Parse 对象**: 创建一个 `ParseObject` 的实例并设置其 `objectId`.
2. **删除对象**: 调用 `delete` 方法从数据库中移除对象。

```dart
Future<void> deleteTodo(String id) async {
  var todo = ParseObject('Todo')..objectId = id;
  await todo.delete();
}
```

## 完整示例代码

这是一个与Back4app后端集成的简单待办事项应用的完整代码。

```dart
import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  const keyApplicationId = 'YOUR_APP_ID_HERE';
  const keyClientKey = 'YOUR_CLIENT_KEY_HERE';
  const keyParseServerUrl = 'https://parseapi.back4app.com';

  await Parse().initialize(keyApplicationId, keyParseServerUrl,
      clientKey: keyClientKey, autoSendSessionId: true);

  runApp(const MaterialApp(home: TodoApp()));
}

class TodoApp extends StatefulWidget {
  const TodoApp({super.key});

  @override
  // ignore: library_private_types_in_public_api
  _TodoAppState createState() => _TodoAppState();
}

class _TodoAppState extends State<TodoApp> {
  List<ParseObject> tasks = [];
  TextEditingController taskController = TextEditingController();

  @override
  void initState() {
    super.initState();
    getTodo();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          primaryColor: Colors.white,
          hintColor: Colors.black,
          scaffoldBackgroundColor: Colors.white,
          appBarTheme:
              AppBarTheme(backgroundColor: Color.fromARGB(255, 68, 122, 246))),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Todo List'),
        ),
        body: Container(
          decoration: BoxDecoration(
            border: Border.all(color: Colors.black),
          ),
          child: Column(
            children: [
              const SizedBox(height: 20),
              _buildTaskInput(),
              const SizedBox(height: 20),
              Expanded(child: _buildTaskList()),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTaskInput() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 20),
      child: Row(
        children: [
          Expanded(
            child: TextField(
              controller: taskController,
              decoration: InputDecoration(
                hintText: 'Enter tasks',
                filled: true,
                fillColor: Colors.grey[200],
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: BorderSide.none,
                ),
              ),
            ),
          ),
          const SizedBox(width: 10),
          ElevatedButton(
            onPressed: addTodo,
            style: ButtonStyle(
                foregroundColor:
                    MaterialStateProperty.all<Color>(Colors.black)),
            child: const Text('Add'),
          ),
        ],
      ),
    );
  }

  Widget _buildTaskList() {
    return ListView.builder(
      itemCount: tasks.length,
      itemBuilder: (context, index) {
        final varTodo = tasks[index];
        final varTitle = varTodo.get<String>('title') ?? '';
        bool done = varTodo.get<bool>('done') ?? false;

        return ListTile(
          title: Row(
            children: [
              Checkbox(
                value: done,
                onChanged: (newValue) {
                  updateTodo(index, newValue!);
                },
              ),
              Expanded(child: Text(varTitle)),
            ],
          ),
          trailing: IconButton(
            icon: const Icon(Icons.delete),
            onPressed: () {
              deleteTodo(index, varTodo.objectId!);
            },
          ),
        );
      },
    );
  }

  Future<void> addTodo() async {
    String task = taskController.text.trim();
    if (task.isNotEmpty) {
      var todo = ParseObject('Todo')
        ..set('title', task)
        ..set('done', false);

      var response = await todo.save();

      if (response.success) {
        setState(() {
          tasks.add(todo);
        });
        taskController.clear();
      } else {
        // Handle error
      }
    }
  }

  Future<void> updateTodo(int index, bool done) async {
    final varTodo = tasks[index];
    final String id = varTodo.objectId.toString();

    var todo = ParseObject('Todo')
      ..objectId = id
      ..set('done', done);

    var response = await todo.save();

    if (response.success) {
      setState(() {
        tasks[index] = todo;
      });
    } else {
      // Handle error
    }
  }

  Future<void> getTodo() async {
    var queryBuilder = QueryBuilder<ParseObject>(ParseObject('Todo'));
    var apiResponse = await queryBuilder.query();

    if (apiResponse.success && apiResponse.results != null) {
      setState(() {
        tasks = apiResponse.results as List<ParseObject>;
      });
    } else {
      // Handle error
    }
  }

  Future<void> deleteTodo(int index, String id) async {
    var todo = ParseObject('Todo')..objectId = id;
    var response = await todo.delete();

    if (response.success) {
      setState(() {
        tasks.removeAt(index);
      });
    } else {
      // Handle error
    }
  }
}
```

### 您的应用程序应该看起来像这样:

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/3advq0EwgQpAeq8ii9lp3_3kcgbfecvvb2myngt1ttp-image.jpg" size="40" width="800" height="1730" position="center" showCaption="false"}

## 结论

您现在已经在使用 Back4App 的 Flutter 应用中实现了基本的 CRUD 操作。本教程演示了如何在 ToDo 应用中添加、检索、更新和删除任务。

