Flutter多功能模型插件omnimodel的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter多功能模型插件omnimodel的使用

本包引入了一个类,该类基本上是一个可以表示为 <code>Map<String, dynamic></code> 的数据包装器。

<strong>OmniModel</strong> 允许以简单且安全的方式访问结构内的数据。该包旨在开发一个简单且模块化的界面,用于与任何非关系型、基于Json的数据库通信。

功能

  • OmniModel 可以将数据包裹起来,并允许轻松且安全地访问。
  • 包含一些有用的工具,如可抑制的自动日志记录行为,当开发者键入错误时,会建议最接近的匹配项。算法使用了非常精确的相似度卷积算法。

使用方法

步骤

  1. 使用各种工厂之一创建 <code>OmniModel</code>
  2. 以受控方式访问条目。
  3. 通过递归解析带有 <code>OmniModel.tokenAsModel()</code> 的模型以模块化方式访问嵌套模型。

高级用法可以在 <code>/example</code> 文件夹中找到。

示例

假设有一个包含以下数据的 <code>Map</code>:

data = {
    "name": "Mario",
    "surname": "Rossi",
    "meta":{
        "age": 25,
        "birth_date": null,
        "address": "Via Prima 12",
    },    
    "interests": [
        "Computer Science",
        "Physics",
        "Food",
        "Outdoor",
    ]
}

<strong>OmniModel</strong> 允许安全地包装数据结构,并轻松处理缺失值和默认情况。创建模型并开始使用它:

var model = OmniModel.fromMap(data);

可以通过连接键来访问嵌套字段(默认分隔符为 <code>"."</code>):

//--&gt; 返回空默认值
var age = model.tokenOrNull&lt;num&gt;("meta.age");

//--&gt; 返回默认值
var birth_date = model.tokenOr&lt;String&gt;("meta.birth_date", "01/01/1970");

//--&gt; 返回不同类型的值
var interests = model.tokenOr&lt;List&lt;String&gt;&gt;("interests", List.empty());

//--&gt; 访问嵌套模型
var metaModel = model.tokenAsModel("meta");
// metaModel 现在是:
//{
//    "age": 25,
//    "birth_date": null,
//    "address": "Via Prima 12",
//}

//--&gt; 用副作用编辑模型,不用担心不存在的嵌套模型,它们会被自动创建
model.edit({
    "birth_date": "08/08/1998",
    "meta.phones": {"mobile":"+39 3331234567"}
});
// 添加兴趣
model.edit({
    "interests": model.tokenOr&lt;List&lt;String&gt;&gt;("interests", List.empty())..add("Maths")
});

//--&gt; 或者获取新的模型实例
var newModel = model.copyWith({
    "birth_date": "08/08/1998",
    "meta.phone": {"mobile":"+39 3331234567"}
});

//--&gt; 获取最接近提供的键的匹配项。使用相似度卷积算法
var closeMatch = model.similar("metadata"); //&lt;--- 将返回 "meta"

Flutter 中的使用

<code>OmniModel</code> 包在声明式编程环境中非常有用。在 <strong>Flutter</strong> 中,防止对每个数据键进行空检查的可能性使代码变得更小且更不易出错。

if(data["meta"] != null &amp;&amp; data["meta"]["birth_date"] != null)
    Text(
        data["meta"]["birth_date"]
    );
else
    Text(
        "Birth date not provided"
    );

//---&gt; 使用 OmniModel,代码更简洁且易于维护。
// 通用的 tokenOr 方法还允许强制执行静态类型

Text(
    model.tokenOr&lt;String&gt;("meta.birth_date","Birth date not provided")
);

完整示例

以下是在 <code>example/omnimodel_example.dart</code> 中提供的完整示例代码:

import "dart:convert";

import "package:omnimodel/omnimodel.dart";
import "package:omnimodel/src/common/logger.dart";

void showStringDistances(String s1, String s2) {
  var distance = s1.similarityConvolution(s2);
  printInfo("■ 相似度卷积距离 ($s1) - ($s2) &gt; $distance");
  distance = s1.levenshtein(s2);
  printInfo("■ 编辑距离 ($s1) - ($s2) &gt; $distance");
}

void main() {
  const map = {
    "first": 0,
    "second": "value",
    "third": {
      "key1": true,
      "key2": 0,
      "key3": [0, 1, 2, 3],
    },
    "fourth": [
      "tag1",
      "tag2",
      "tag3",
    ],
  };

  //* 运行命令:
  //* dart run omnimodel_examples.dart

  // 从 map 创建模型
  var model = OmniModel.fromMap(map);

  // 注释掉以禁用提示打印。在生产环境中有条件地禁用打印功能。
  // OmniModelPerferences.enableHints = false;
  // Flutter:
  // OmniModelPreferences.enableHints = kDebugMode;

  printInfo("""
  
███╗░░██╗██╗██╗░██████╗
████╗░██║██║██║██╔════╝
██╔██╗██║██║██║╚█████╗░
██║╚████║██║██║░╚═══██╗
██║░╚███║██║██║██████╔╝
╚═╝░░╚══╝╚═╝╚═╝╚═════╝░

█▀▀ ▀▄▀ ▄▀█ █▀▄▀█ █▀█ █░░ █▀▀ █▀
██▄ █░█ █▀█ █░▀░█ █▀▀ █▄▄ ██▄ ▄█                                                    
""");

  printInfo("map ${JsonEncoder.withIndent(" ").convert(map)}");
  print("■" * 100);
  printInfo("■ map[first] &gt; ${model.tokenOrNull("first")}\n${"-" * 100}");
  printInfo(
    "■ map[first] as String &gt; ${model.tokenOrNull&lt;String&gt;("first")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[second] as String &gt; ${model.tokenOr("second", "not found")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[second] as List &gt; ${model.tokenOr&lt;List&gt;("second", List.empty())}\n${"-" * 100}",
  );
  printInfo(
    "■ map[third] as Map &gt; ${model.tokenOrNull&lt;Map&gt;("third")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[third][key3] with OmniModel concatenation &gt; ${model.tokenAsModel("third").tokenOrNull("key3")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[third][key3] with combined path &gt; ${model.tokenOrNull("third.key3")}\n${"-" * 100}",
  );
  printInfo("■ map[fourth] as Map &gt; ${model.tokenOr("fourth", {"new_key": 1})}\n${"-" * 100}");
  printInfo(
    "■ map[fourth] as List &gt; ${model.tokenOrNull&lt;List&gt;("fourth")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[fifth] (not exists) &gt; ${model.tokenOrNull("fifth")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[fifth] (not exists) with default value &gt; ${model.tokenOr&lt;String&gt;("fifth", "not found")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[fourth1] (mispelled key) &gt; ${model.tokenOrNull("fourth1")}\n${"-" * 100}",
  );
  printInfo(
    "■ map[third][key4] (mispelled key) &gt; ${model.tokenOrNull("third.key4")}\n${"-" * 100}",
  );
  printInfo("■ Similar");
  printInfo("\tmost similar to thirt &gt; ${model.similar("thirt")}");
  printInfo("\tmost similar to secondly &gt; ${model.similar("secondly")}");
  printInfo("\tmost similar to fifth &gt; ${model.similar("fifth")}");

  printInfo("■ Iterate");
  model.json.forEach(
    (key, value) =&gt; printInfo("($key, $value)"),
  );
  print("■" * 100);
  printInfo("EXTENSIONS");

  showStringDistances("Hello World!", "Hello mad World!");
  showStringDistances("Hello World!", "Hello World!");
  showStringDistances("Hello World!", "Hello World.");
  showStringDistances("abba", "aaaa");
  showStringDistances("ab ba", "aaaa");

  var mapCopy = OmniModel.fromMap(map).json;
  printInfo("■ Deep update");
  printInfo("\tinitial map = $mapCopy");
  var edited = mapCopy.deepUpdate(["third", "key2"], "string!");
  printInfo('\tdeep updated [third, key2] &lt; "string!" = $edited');
  edited = mapCopy.deepUpdate(["third", "key4"], ":D");
  printInfo('\tdeep updated [third, key4] &lt; ":D" = $edited');
  edited = mapCopy.deepUpdate(["third", "key2", "new_key"], "newkey!");
  printInfo('\tdeep updated [third, key2, new_key] &lt; "newkey!" = $edited');
}

更多关于Flutter多功能模型插件omnimodel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter多功能模型插件omnimodel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用omnimodel插件的示例代码案例。omnimodel是一个假想的Flutter插件,用于处理多功能模型,但请注意,由于这是一个假设的插件,具体的API和函数可能会有所不同。不过,以下代码提供了一个通用的结构,展示如何集成和使用一个类似的插件。

首先,确保你已经在pubspec.yaml文件中添加了omnimodel依赖:

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

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

接下来,在你的Flutter项目中,你可以按照以下步骤使用omnimodel插件:

1. 导入插件

在你的Dart文件中导入omnimodel插件:

import 'package:omnimodel/omnimodel.dart';

2. 初始化插件

在应用的入口文件(通常是main.dart)中初始化插件(如果插件需要初始化的话):

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // 假设omnimodel有一个全局初始化方法
  OmniModel.initialize();
  runApp(MyApp());
}

3. 使用插件功能

假设omnimodel插件提供了加载、处理和保存模型的功能,以下是如何使用这些功能的示例代码:

import 'package:flutter/material.dart';
import 'package:omnimodel/omnimodel.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  OmniModel.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'OmniModel Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: OmniModelDemo(),
    );
  }
}

class OmniModelDemo extends StatefulWidget {
  @override
  _OmniModelDemoState createState() => _OmniModelDemoState();
}

class _OmniModelDemoState extends State<OmniModelDemo> {
  OmniModel? _model;
  String _status = "Loading model...";

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

  Future<void> _loadModel() async {
    try {
      // 假设omnimodel有一个从资产加载模型的方法
      _model = await OmniModel.loadFromAsset('assets/models/example.model');
      setState(() {
        _status = "Model loaded successfully!";
      });
    } catch (e) {
      setState(() {
        _status = "Failed to load model: $e";
      });
    }
  }

  Future<void> _processModel() async {
    if (_model != null) {
      try {
        // 假设omnimodel有一个处理模型的方法
        var result = await _model!.process();
        setState(() {
          _status = "Model processed with result: $result";
        });
      } catch (e) {
        setState(() {
          _status = "Failed to process model: $e";
        });
      }
    } else {
      setState(() {
        _status = "No model loaded!";
      });
    }
  }

  Future<void> _saveModel() async {
    if (_model != null) {
      try {
        // 假设omnimodel有一个保存模型到文件的方法
        await _model!.saveToFile('example_processed.model');
        setState(() {
          _status = "Model saved successfully!";
        });
      } catch (e) {
        setState(() {
          _status = "Failed to save model: $e";
        });
      }
    } else {
      setState(() {
        _status = "No model loaded!";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OmniModel Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(_status),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _processModel,
              child: Text('Process Model'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: _saveModel,
              child: Text('Save Model'),
            ),
          ],
        ),
      ),
    );
  }
}

注意

  1. 由于omnimodel是一个假设的插件,上述代码中的OmniModel类及其方法(如loadFromAssetprocesssaveToFile)需要根据实际插件的API进行调整。
  2. 确保在pubspec.yaml中正确配置了资产文件路径,如果omnimodel插件需要从资产中加载模型。
  3. 错误处理应根据实际需求进行增强,以提供更好的用户体验。

希望这个示例能帮助你理解如何在Flutter项目中使用一个类似omnimodel的多功能模型插件。如果你有更具体的需求或插件的API细节,请提供更多信息以便给出更准确的代码示例。

回到顶部