Flutter开发中如何用变量作为Hive对象属性名实现动态查询
问题原因
Dart是静态类型语言,使用.操作符访问属性时,会直接把.后面的标识符当做固定的属性名编译,不会读取该标识符对应的字符串变量值,因此你的代码实际是在查找HiveDocMod上名为attributeSelect的属性,而非变量存储的test等属性名,自然会抛出找不到方法的错误。
解决方案
方案1:模型类新增属性取值方法(最优)
在你的HiveDocMod类中新增一个根据属性名字符串返回对应布尔值的方法,示例如下:
@HiveType(typeId: 0) // 保留你原有类的Hive注解即可 class HiveDocMod extends HiveObject { // 你原有定义的181个布尔属性,示例如下: @HiveField(0) bool test = false; @HiveField(1) bool vesselId = false; // ... 其余属性保持不变 // 新增此方法 bool getAttributeByName(String attrName) { switch(attrName) { case 'test': return test; case 'vesselId': return vesselId; // 补充剩余所有属性的case分支即可 default: throw ArgumentError('未找到对应属性:$attrName'); } } }
修改你原有查询逻辑里的判断代码:
// 按属性查询 if (myBox.getAt(i).getAttributeByName(attributeSelect)) { _hiveDocs.add(myBox.getAt(i)); }
181个case分支不需要手动逐行写,可以写个简单的本地脚本根据属性列表自动生成对应代码,成本极低。
方案2:新增Map属性同步存储布尔值
如果你不想维护大量case分支,可以在HiveDocMod中新增一个Map类型的Hive字段,专门存储所有布尔属性的键值对:
// 加入HiveDocMod类中 @HiveField(182) Map<String, bool> attrMap = {};
每次给布尔属性赋值时,同时同步更新attrMap对应键的值,查询时直接读取Map即可:
// 按属性查询 if (myBox.getAt(i).attrMap[attributeSelect] == true) { _hiveDocs.add(myBox.getAt(i)); }
注意
不要使用dart:mirrors反射方案实现动态取值,Flutter的AOT编译模式不支持反射功能,打包后会直接崩溃,无法正常使用。
内容的提问来源于stack exchange,提问作者spikelucky
相关产品推荐
相关产品推荐

