Flutter多字段搜索异常:仅emp_name可搜索,announcement_title无效
实现双字段搜索的修复方案
当前代码仅支持通过emp_name字段过滤搜索公告数据,无法通过announcement_title字段匹配搜索结果,以下是问题定位及修复方案:
原始JSON响应数据
{ "status": 200, "data": [ { "announcement_title": "title", "announcement": "This is an announcement", "emp_name": "Somdutta Sengupta", "profile_photo": "202209191410925IMG_20220919_135715.jpg", "created_at": "2022-08-18 02:47:00" }, { "announcement_title": "title of an announcement", "announcement": "This is an announcement", "emp_name": "Siddhartha Chatterjee", "profile_photo": "202210211837932image_cropper_1666357661507.jpg", "created_at": "2022-08-18 02:47:00" }, { "announcement_title": "This is title of another announcement", "announcement": "This is an announcement body", "emp_name": "Shaikh Salim Akhter", "profile_photo": "202210291143921image_cropper_1667024019467.jpg", "created_at": "2022-08-18 02:47:00" }, { "announcement_title": "Here is an Announcement", "announcement": "This here is a test announcement for the System Team.", "emp_name": "Shaikh Salim Akhter", "profile_photo": "202210291143921image_cropper_1667024019467.jpg", "created_at": "2022-10-18 05:20:12" }, { "announcement_title": "Another Test Title", "announcement": "Another Announcement for System.", "emp_name": "Shaikh Salim Akhter", "profile_photo": "202210291143921image_cropper_1667024019467.jpg", "created_at": "2022-10-18 05:38:34" }, { "announcement_title": "And Another Announcement", "announcement": "Another Test Annoucement for the System Team.", "emp_name": "Shaikh Salim Akhter", "profile_photo": "202210291143921image_cropper_1667024019467.jpg", "created_at": "2022-10-18 07:13:57" }, { "announcement_title": "Test One", "announcement": "Test Announcement", "emp_name": "Shaikh Salim Akhter", "profile_photo": "202210291143921image_cropper_1667024019467.jpg", "created_at": "2022-10-18 07:17:57" } ] }
原始搜索调用代码
List<dynamic> data = []; List<dynamic> query = []; @override void initState() { // TODO: implement initState Provider.of<AnnouncementViewModel>(context, listen: false) .getAllAnouncements() //API调用入口 .then((_) { setState(() { isLoading = false; data = Provider.of<AnnouncementViewModel>(context, listen: false) .announcementFilter; //将API返回数据复制到data变量 query = data; }); }); initialise(); super.initState(); } //搜索方法 searchByQuery(String search) { setState(() { query = data .where((element) => element['emp_name'].toLowerCase().contains(search.toLowerCase())) .toList(); query = data .where((element) => element['announcement_title'] .toLowerCase() .contains(search.toLowerCase())) .toList(); }); }
原始AnnouncementViewModel代码
Map<String, dynamic> _allAnouncements = {}; List<dynamic> _announcementFilter = []; Map<String, dynamic> get allAnouncements { return {..._allAnouncements}; } List<dynamic> get announcementFilter { //供页面获取API数据的getter方法 return [..._announcementFilter]; } Future<void> getAllAnouncements() async { SharedPreferences localStorage = await SharedPreferences.getInstance(); _announcementFilter = []; var response = await http.get(Uri.parse(AppUrl.allAnouncements), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ${localStorage.getString('token')}' }); if (response.statusCode == 200) { _allAnouncements = json.decode(response.body); _allAnouncements['data'] .forEach((value) => _announcementFilter.add(value)); } else { _allAnouncements = {}; } if (kDebugMode) { print('ALL ANOUNCEMENTS: $_allAnouncements'); print('ALL FILTERED ANOUNCEMENTS: $_announcementFilter'); } notifyListeners(); }
问题定位
searchByQuery方法中存在逻辑错误:两次对query变量赋值,第二次的搜索结果会直接覆盖第一次的结果,导致最终只有单个字段的搜索逻辑生效。正确逻辑应该是将两个字段的搜索条件用逻辑或(||)合并,只要满足其中一个条件就保留数据项。
修复后的搜索方法代码
//修复后的搜索方法 searchByQuery(String search) { setState(() { final lowerCaseSearch = search.toLowerCase(); query = data .where((element) => element['emp_name'].toLowerCase().contains(lowerCaseSearch) || element['announcement_title'].toLowerCase().contains(lowerCaseSearch)) .toList(); }); }
额外优化建议
为避免字段值为null导致的空指针异常,可添加空值判断:
//带空值判断的优化版搜索方法 searchByQuery(String search) { setState(() { final lowerCaseSearch = search.toLowerCase(); query = data .where((element) => (element['emp_name']?.toLowerCase() ?? '').contains(lowerCaseSearch) || (element['announcement_title']?.toLowerCase() ?? '').contains(lowerCaseSearch)) .toList(); }); }
内容的提问来源于stack exchange,提问作者coolhack7
相关产品推荐
相关产品推荐

