Flutter数据规范化插件normalizr的使用

Flutter数据规范化插件normalizr的使用

关于

许多API(公开或私有的)返回的数据是JSON格式,并且这些JSON数据通常是深度嵌套的对象。在这样的结构中使用数据往往非常困难。

Normalizr 是一个小型但功能强大的工具,用于根据模式定义将JSON数据规范化为具有ID的嵌套实体,并将它们聚集在字典中。

链接

使用

示例输入JSON

{
  "id": "123",
  "author": {"id": "1", "name": "Paul"},
  "title": "My awesome blog post",
  "comments": [
    {
      "id": "324",
      "commenter": {"id": "2", "name": "Nicole"}
    }
  ]
}

规范化

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

// 定义用户模式
final user = Entity('users');

// 定义评论模式
final comment = Entity('comments', {
  'commenter': Ref('users'),
});

// 定义文章模式
final article = Entity('articles', {
  'author': Ref('users'),
  'comments': Ref.list('comments'),
});

void main() {
  // 设置
  normalizr.addAll([user, comment, article]);
  
  // 输入数据
  final data = {
    "id": "123",
    "author": {"id": "1", "name": "Paul"},
    "title": "My awesome blog post",
    "comments": [
      {
        "id": "324",
        "commenter": {"id": "2", "name": "Nicole"}
      }
    ]
  };

  // 规范化数据
  final normalizedData = normalize(data, article);
  // 输出
  final encoder = JsonEncoder.withIndent('  ');
  String prettyJson = encoder.convert(normalizedData);
  print(prettyJson);
}

输出结果

{
  "result": "123",
  "type": "articles",
  "entities": {
    "users": {
      "1": {
        "id": "1",
        "name": "Paul"
      },
      "2": {
        "id": "2",
        "name": "Nicole"
      }
    },
    "comments": {
      "324": {
        "id": "324",
        "commenter": "2"
      }
    },
    "articles": {
      "123": {
        "id": "123",
        "author": "1",
        "title": "My awesome blog post",
        "comments": [
          "324"
        ]
      }
    }
  }
}

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

1 回复

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


在Flutter开发中,normalizr 是一个流行的JavaScript库,用于将数据规范化(normalizing),使得嵌套的数据结构变得平坦且易于管理。尽管 normalizr 本身是为JavaScript设计的,Flutter社区也开发了一些类似功能的库,可以帮助我们在Flutter应用中处理类似的数据规范化需求。

虽然Flutter没有直接的normalizr实现,但我们可以使用Dart语言的一些特性和库来达到类似的效果。下面是一个使用Dart的Map和List操作来模拟数据规范化的简单示例。这个示例不会依赖特定的Flutter插件,但展示了如何手动处理嵌套数据结构。

示例场景

假设我们有一个API返回的用户数据,其中包含了用户的帖子,每个帖子又包含评论。我们的目标是将这些嵌套的数据结构展开为一个更平坦的形式。

原始数据结构

var rawData = [
  {
    'id': '1',
    'name': 'Alice',
    'posts': [
      {
        'id': '101',
        'title': 'Post by Alice 1',
        'comments': [
          {'id': '1001', 'text': 'Comment 1'},
          {'id': '1002', 'text': 'Comment 2'},
        ],
      },
      {
        'id': '102',
        'title': 'Post by Alice 2',
        'comments': [
          {'id': '1003', 'text': 'Comment 3'},
        ],
      },
    ],
  },
  // 更多用户数据...
];

目标数据结构

我们希望将上述数据转换为以下形式:

{
  'users': {
    '1': { 'id': '1', 'name': 'Alice', 'posts': ['101', '102'] },
    // 更多用户...
  },
  'posts': {
    '101': { 'id': '101', 'userId': '1', 'title': 'Post by Alice 1', 'comments': ['1001', '1002'] },
    '102': { 'id': '102', 'userId': '1', 'title': 'Post by Alice 2', 'comments': ['1003'] },
    // 更多帖子...
  },
  'comments': {
    '1001': { 'id': '1001', 'postId': '101', 'text': 'Comment 1' },
    '1002': { 'id': '1002', 'postId': '101', 'text': 'Comment 2' },
    '1003': { 'id': '1003', 'postId': '102', 'text': 'Comment 3' },
    // 更多评论...
  },
}

实现代码

void main() {
  var rawData = [
    {
      'id': '1',
      'name': 'Alice',
      'posts': [
        {
          'id': '101',
          'title': 'Post by Alice 1',
          'comments': [
            {'id': '1001', 'text': 'Comment 1'},
            {'id': '1002', 'text': 'Comment 2'},
          ],
        },
        {
          'id': '102',
          'title': 'Post by Alice 2',
          'comments': [
            {'id': '1003', 'text': 'Comment 3'},
          ],
        },
      ],
    },
    // 更多用户数据...
  ];

  var normalizedData = normalizeData(rawData);
  print(normalizedData);
}

Map<String, Map<String, dynamic>> normalizeData(List<Map<String, dynamic>> users) {
  var entities = {
    'users': {},
    'posts': {},
    'comments': {},
  };

  users.forEach((user) {
    var userId = user['id']!;
    entities['users'][userId] = {
      'id': userId,
      'name': user['name']!,
      'posts': [],
    };

    user['posts']!.forEach((post) {
      var postId = post['id']!;
      var postEntity = {
        'id': postId,
        'userId': userId,
        'title': post['title']!,
        'comments': [],
      };
      entities['posts'][postId] = postEntity;
      entities['users'][userId]!['posts']!.add(postId);

      post['comments']!.forEach((comment) {
        var commentId = comment['id']!;
        var commentEntity = {
          'id': commentId,
          'postId': postId,
          'text': comment['text']!,
        };
        entities['comments'][commentId] = commentEntity;
        entities['posts'][postId]!['comments']!.add(commentId);
      });
    });
  });

  return entities;
}

总结

尽管Flutter没有直接的normalizr插件,但通过上述代码示例,我们可以看到如何使用Dart的基本功能来手动规范化数据。这种方法可以应用于各种复杂的数据结构,帮助我们更好地管理和访问嵌套数据。如果需要处理更复杂的数据规范化需求,可以考虑使用更强大的数据管理工具或库,如Redux、MobX等状态管理解决方案。

回到顶部