listDecoder<E> function
构建列表解码器的辅助函数
将单元素解码器转换为完整列表解码器,保持正确的泛型类型。
解决 Dart 泛型擦除导致的 List<dynamic> 无法转换为 List<T> 的问题。
示例:
SmartRequest<List<User>>(
path: '/users',
fromJson: listDecoder(User.fromJson),
)
// Protobuf 示例
SmartRequest<List<FamilyData>>(
path: '/family/list',
fromJson: listDecoder((json) => FamilyData.create()..mergeFromProto3Json(json)),
)
// 过滤空数据示例(例如后端返回包含 null/{} 的列表)
SmartRequest<List<User>>(
path: '/users',
fromJson: listDecoder(
User.fromJson,
preFilter: (item) => item is Map<String, dynamic> && item.isNotEmpty,
),
)
// 解码后过滤示例(filter 可以拿到范型 E,例如 User)
SmartRequest<List<User>>(
path: '/users',
fromJson: listDecoder(
User.fromJson,
filter: (user) => user.id > 0,
),
)
Implementation
JsonDecoder<List<E>> listDecoder<E>(
E Function(Map<String, dynamic>) itemDecoder, {
/// 解码前过滤:拿到原始列表元素(dynamic),用于过滤 null/{} 等脏数据。
bool Function(dynamic raw)? preFilter,
/// 解码后过滤:拿到 E(例如 User),用于业务层按字段过滤。
bool Function(E decoded)? filter,
}) {
return (dynamic data) {
if (data is! List) {
throw ArgumentError('Expected List but got ${data.runtimeType}');
}
final result = <E>[];
for (final item in data) {
if (preFilter != null && !preFilter(item)) continue;
final decoded = itemDecoder(item as Map<String, dynamic>);
if (filter != null && !filter(decoded)) continue;
result.add(decoded);
}
return result;
};
}