📜  Flutter Bloc – 基本搜索

📅  最后修改于: 2022-05-13 01:54:34.240000             🧑  作者: Mango

Flutter Bloc – 基本搜索

Flutter是一个强大的工具,可以从单一代码库开发酷炫的 android 和 ios 应用程序,更像是 PWA。在本文中,我们将指导您如何为搜索模块设计 Bloc 架构。

目标:对于初学者,我们的目标是创建一个具有搜索字段的应用程序,该应用程序可以具有连续的搜索页面并保存所有结果。

先决条件:

  • 必须具备业务逻辑和全局状态管理的基本知识

让我们开始吧。

执行:

首先,让我们实现一个名为 Search 的基本 Bloc,它正在创建一个 bloc 文件、一个事件文件、状态和一个用于在本地或远程获取数据的存储库。

Dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:medcomp/models/med.model.dart';
 
class SearchEvent extends Equatable {
  @override
  List get props => [];
}
 
class SearchEventLoadData extends SearchEvent {
  final String str;
  SearchEventLoadData({@required this.str});
}

Dart
class SearchEventLoadData extends SearchEvent {
  final List strList;
  final List dataList;
  SearchEventLoadData({@required this.strList, @required this.dataList});
}
 
class SearchEventPopSearch extends SearchEvent {}


Dart
import 'package:equatable/equatable.dart';
 
class SearchState extends Equatable {
  @override
  List get props => [];
}
 
class SearchStateNotLoaded extends SearchState {}
 
class SearchStateLoading extends SearchState {}
 
class SearchStateLoaded extends SearchState {
  final List strList;
  final List dataList;
  SearchStateLoaded(this.strList, this.dataList);
}
 
class SearchStateError extends SearchState {
  final message;
  SearchStateError(this.message);
}

Dart
import 'package:bloc/bloc.dart';
import 'package:medcomp/events/search.event.dart';
import 'package:medcomp/models/search.model.dart';
import 'package:medcomp/repositories/search.repo.dart';
import 'package:medcomp/states/search.state.dart';
 
class SearchBloc extends Bloc {
  @override
  SearchState get initialState => SearchStateNotLoaded();
 
  SearchRepo _searchRepo = SearchRepo();
 
  @override
  Stream mapEventToState(SearchEvent event) async* {
    if (event is SearchEventLoadData) {
      yield SearchStateLoading();
      try {
        ResultModel resultModel = await this._searchRepo.getDetails(event.strList.last);
        event.dataList.add(resultModel);
        if (search == null) {
          String error = this._searchRepo.message;
          yield SearchStateError(error);
        } else {
          yield SearchStateLoaded(event.strList, event.dataList);
        }
      } catch (e) {
        yield SearchStateError(e);
      }
    }
 
    if (event is SearchEventPopSearch) {
      try {
        if (state is SearchStateLoaded) {
          var oldState = (state as SearchStateLoaded);
          yield SearchStateLoading();
          oldState.strList.removeLast();
          oldState.dataList.removeLast();
          yield SearchStateLoaded(oldState.strList, oldState.dataList);
        } else {
          yield SearchStateError('state is SearchStateLaoded false');
        }
      } catch (e) {
        yield SearchStateError('Error in search remove $e');
      }
    }
  }
}


这是您在掌握了flutter的基本知识后第一次创建的事件文件,所以现在我们想要您添加一个str 列表列表,该列表将存储所有先前搜索的短语或字符串。要保存结果以节省用户的时间,您还可以创建结果模型列表以将它们存储在您的块中。我们称之为结果模型列表。此外,创建一个扩展 SearchEvent 的类,该类将在弹出特定结果页面时调用。

Dart

class SearchEventLoadData extends SearchEvent {
  final List strList;
  final List dataList;
  SearchEventLoadData({@required this.strList, @required this.dataList});
}
 
class SearchEventPopSearch extends SearchEvent {}

从现在开始,我们已经创建了变量来存储我们之前搜索过的项目,是时候实现这些状态了。这里的基本概念是将整个数据列表暴露给视图模型并渲染列表的最后一个元素,因为我们使用堆栈并且最后推送的数据是最近的搜索。

Dart

import 'package:equatable/equatable.dart';
 
class SearchState extends Equatable {
  @override
  List get props => [];
}
 
class SearchStateNotLoaded extends SearchState {}
 
class SearchStateLoading extends SearchState {}
 
class SearchStateLoaded extends SearchState {
  final List strList;
  final List dataList;
  SearchStateLoaded(this.strList, this.dataList);
}
 
class SearchStateError extends SearchState {
  final message;
  SearchStateError(this.message);
}

现在是时候添加一个 bloc 文件层来组合这些组件了。我们创建了一个SearchRepo ,它将负责从 API 或本地数据库中获取数据并让 repo 文件正常工作。

Dart

import 'package:bloc/bloc.dart';
import 'package:medcomp/events/search.event.dart';
import 'package:medcomp/models/search.model.dart';
import 'package:medcomp/repositories/search.repo.dart';
import 'package:medcomp/states/search.state.dart';
 
class SearchBloc extends Bloc {
  @override
  SearchState get initialState => SearchStateNotLoaded();
 
  SearchRepo _searchRepo = SearchRepo();
 
  @override
  Stream mapEventToState(SearchEvent event) async* {
    if (event is SearchEventLoadData) {
      yield SearchStateLoading();
      try {
        ResultModel resultModel = await this._searchRepo.getDetails(event.strList.last);
        event.dataList.add(resultModel);
        if (search == null) {
          String error = this._searchRepo.message;
          yield SearchStateError(error);
        } else {
          yield SearchStateLoaded(event.strList, event.dataList);
        }
      } catch (e) {
        yield SearchStateError(e);
      }
    }
 
    if (event is SearchEventPopSearch) {
      try {
        if (state is SearchStateLoaded) {
          var oldState = (state as SearchStateLoaded);
          yield SearchStateLoading();
          oldState.strList.removeLast();
          oldState.dataList.removeLast();
          yield SearchStateLoaded(oldState.strList, oldState.dataList);
        } else {
          yield SearchStateError('state is SearchStateLaoded false');
        }
      } catch (e) {
        yield SearchStateError('Error in search remove $e');
      }
    }
  }
}