Flutter数据同步插件wire的使用

Flutter数据同步插件Wire的使用

Wire概述

Wire是一个用于解耦用户界面(UI)与业务逻辑的库。它包含两个层次:通信层和数据容器层。

通信层

通信层由信号(字符串键)及其关联处理程序组成,并绑定到特定的作用域(Wire对象的实例)。该层主要方法包括 Wire.addWire.send

数据容器层

数据容器层是一个内存中的键值映射,每个值都是一个 WireData 实例——一个观察者,持有动态值并可以订阅更新。其主要方法为 Wire.data

Wire在Flutter中的使用

在Flutter中,Wire提供了一个特殊的Widget——WireDataBuilder<T>,使你可以轻松地从UI中消费数据并发送信号。

示例代码

步骤1:添加Wire和WireListener

在系统中添加Wire和WireListener。在这种情况下,控制器自身更新数据。

class CounterController {
  CounterController() {
    // 1. 作用域,字符串键,处理函数
    Wire.add(this, CounterSignalsKeys.INCREASE, (dynamic payload, wireId) async {
      // 4. 异步处理信号
      // 新值可以是函数或普通值
      Wire.data(CounterDataKeys.COUNT, value: (value) {
        final count = value as int?;
        // 6. 更新数据
        return (count ?? 0) + 1;
      });
    });
    // 处理CounterSignalsKeys.DECREASE的处理函数请参见源代码
  }
}

步骤2:视图订阅数据变化并知道如何更新自己

视图订阅数据变化并根据这些变化更新自身。

class CounterDisplay extends StatelessWidget {
  CounterDisplay() : super(key: ArchSampleKeys.statsCounter);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: WireDataBuilder<int>(
        dataKey: DataKeys.COUNT, // 数据键(字符串)
        builder: (context, notCompletedCount) {
          var allTodoCount = (Wire.data(DataKeys.LIST).value as List).length; // 访问数据
          var numCompleted = allTodoCount - notCompletedCount;
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('未完成任务数: $notCompletedCount'),
              Text('已完成任务数: $numCompleted'),
            ],
          );
        },
      ),
    );
  }
}

步骤3:将UI事件转换为信号

将UI事件转换为信号。

class CounterButton extends StatelessWidget {
  CounterButton(String title, String signal):super(key: ValueKey(title)) {
    return ElevatedButton(
      onPressed: () => Wire.send(signal),
      child: Text(title),
    );
  }
}

步骤4:中间件捕获系统中的所有操作

中间件捕获系统中的所有操作,例如存储计数器值到localStorage。

class CounterStorageMiddleware extends WireMiddleware {
  final ls = window.localStorage;

  int getInitialValue() {
    return ls.containsKey(CounterDataKeys.COUNT) ?
      int.parse(ls[CounterDataKeys.COUNT]) : 0;
  }

  @override
  void onData(String key, prevValue, nextValue) {
    print('&gt; CounterMiddleware -&gt; onData: key = ${key} | ${prevValue}-${nextValue}');
    if (key == CounterDataKeys.COUNT) {
      if (nextValue != null) ls[key] = nextValue.toString();
      else { if (ls.containsValue(key)) ls.remove(key); }
    }
  }

  @override void onAdd(Wire wire) { }
  @override void onRemove(String signal, [Object scope, listener]) { }
  @override void onSend(String signal, [data, scope]) { }
}

初始化

初始化Wire,设置初始值并注册中间件。

void main() {
  /// COUNTER EXAMPLE ======================================
  final counterStorageMiddleware = CounterStorageMiddleware();
  // 设置初始值从localStorage,可以在CounterStorageMiddleware构造函数中设置。
  Wire.data(CounterDataKeys.COUNT, value: counterStorageMiddleware.getInitialValue());
  // 在设置初始值后注册中间件以防止保存初始值
  Wire.middleware(counterStorageMiddleware);
  // 实例化控制器以注册所有信号处理
  CounterController();
  // 查找index.html中的根元素并将其映射到功能组件
  final root = document.querySelector('#root');
  ApplicationView(root as DivElement?);
}

更多关于Flutter数据同步插件wire的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据同步插件wire的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用wire插件进行数据同步的示例代码。wire是一个强大的Flutter插件,用于在客户端和服务器之间同步数据。这里我们假设你已经安装了wire插件,并且有一个可以与之同步的后端服务。

1. 安装插件

首先,确保在你的pubspec.yaml文件中添加了wire依赖:

dependencies:
  flutter:
    sdk: flutter
  wire_flutter: ^最新版本号  # 请替换为实际版本号

然后运行flutter pub get来安装依赖。

2. 配置WireClient

你需要配置WireClient以连接到你的后端服务。通常,这包括设置API密钥和服务器URL。

import 'package:wire_flutter/wire_flutter.dart';

// 假设你的后端服务需要API密钥
final String apiKey = 'your_api_key_here';
final String serverUrl = 'https://your-backend-service.com';

void configureWireClient() {
  WireClient.configure(
    apiKey: apiKey,
    serverUrl: serverUrl,
    onConnectionStateChanged: (state) {
      print('Connection state changed: $state');
    },
  );
}

3. 定义数据模型

使用wire_flutter提供的注解来定义你的数据模型。这些注解会告诉wire如何处理这些模型类的同步。

import 'package:wire_flutter/annotations.dart';

@WireModel()
class Todo {
  @WireField(key: 'id')
  final String id;

  @WireField(key: 'title')
  String title;

  @WireField(key: 'completed')
  bool completed;

  Todo({required this.id, required this.title, this.completed = false});
}

4. 同步数据

使用WireClient的同步方法来获取和更新数据。

import 'dart:async';

// 假设你有一个Todo的集合
late List<Todo> todos;

Future<void> fetchTodos() async {
  todos = await WireClient.syncList<Todo>(
    modelName: 'Todo',  // 这里的名称应该与后端服务中的模型名称匹配
    query: Map.fromEntries([
      MapEntry('completed', false.toString()),  // 例如,获取所有未完成的Todo
    ]),
  );
  print('Fetched todos: $todos');
}

Future<void> updateTodo(Todo todo) async {
  await WireClient.updateModel(todo);
  print('Updated todo: $todo');
}

5. 使用数据

现在你可以在你的Flutter应用中使用这些数据了。例如,在一个简单的列表中显示Todo项:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    configureWireClient();
    fetchTodos();  // 在应用启动时获取Todo列表
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Todo List'),
        ),
        body: todos.isNotEmpty
            ? ListView.builder(
                itemCount: todos.length,
                itemBuilder: (context, index) {
                  final todo = todos[index];
                  return ListTile(
                    title: Text(todo.title),
                    trailing: Switch(
                      value: todo.completed,
                      onChanged: (newValue) async {
                        todo.completed = newValue;
                        await updateTodo(todo);
                        // 更新UI,这里由于Flutter的状态管理机制,UI会自动刷新
                      },
                    ),
                  );
                })
            : Center(child: Text('No todos found')),
      ),
    );
  }
}

以上代码示例展示了如何在Flutter项目中使用wire插件进行数据的同步。请注意,这只是一个基本的示例,实际应用中可能需要根据具体需求进行更多的配置和处理。希望这对你有所帮助!

回到顶部