実現したいこと:
検索ボックスに文字が入力(変更)されるたびに、検索結果が返される。
この機能をクリーンアーキテクチャに近い形で実装する
flutter / flutter-riverpod / get_it
想定:
- 検索ボックスの入力値をSearchViewModelのqueryにバインディングする。
- 変更通知を受け取るたびにExploreControllerを呼び出し、
- ExploreControllerがSearchUseCaseを呼び出し、
- SearchUseCase内で検索結果を取得後、SearchUseCaseがSearchPresenterを呼び出し、
- SearchPresenterがSearchViewModelのsetItemsを呼びだす。
viewmodel内でviewmodelを呼び出すことになっているのが奇妙ですが、
データバインディングを使用して、クリーンアーキテクチャもしようするとこのような流れが吉なのでは思いました。
もし、想定が間違っている場合、良い実現方法がある場合、指摘してください!
サンプルコード
下のような感じで実装を考えています。
実際は、providerを使用しているため、refをcontrollerからpresenterまで受け渡ししてviewmodelを呼び出さないといけないので、 関係ない層がflutter_riverpodに依存してしまうし、無駄なrefの受け渡しが増えてしまうので困っています。
dart
1final searchViewModelProvider = 2 ChangeNotifierProvider((ref) => DI<SearchViewModel>()); 3 4class SearchViewModel extends ChangeNotifier { 5 final ExploreController _exploreController; 6 SearchViewModel(this._exploreController); 7 8 List<MyResult> _filteredItems = []; 9 String _query = ""; 10 11 String get query => _query; 12 set query(String value) { 13 _query = value; 14 _fireController(); 15 notifyListeners(); 16 } 17 18 List<MyResult> get filteredItems => _filteredItems; 19 set filteredItems(List<MyResult> values) { 20 _filteredItems = values; 21 notifyListeners(); 22 } 23 24 Future<void> _fireController() async { 25 if (_query.isNotEmpty) { 26 _exploreController.search(_query); 27 } 28 } 29} 30 31 32//controller 33//flutter/material.dart have searchcontroller class 34class ExploreController { 35 SearchInteractor _searchInteractor; 36 ExploreController(this._searchInteractor); 37 38 void search(String query) { 39 _searchInteractor.execute(query); 40 } 41} 42 43 44 45 46//usecase 47class SearchInteractor { 48 MyRepository _myRepository ; 49 SearchPresenter _presenter; 50 SearchInteractor(this._myRepository,this._presenter); 51 52 void execute(String input) async{ 53 List<MyResult> results=await _myRepository.getMyResults(input); 54 _presenter.execute(results); 55 } 56} 57 58 59//presenter 60class SearchPresenter { 61 SearchViewModel _viewModel ; 62 SearchPresenter(this._viewModel); 63 64 void execute(List<MyResult> input) async{ 65 _viewModel.filteredItems=input; 66 } 67}
dart
1 2final DI = GetIt.instance; 3 4void setupLocator() { 5 6 //repository 7 DI.registerSingleton<MyRepository>(() => MyRepository()); 8 9 //viewmodel 10 DI.registerFactory<SearchViewModel>( 11 () => SearchViewModel(DI<ExploreController>())); 12 13 //controller 14 DI.registerFactory<ExploreController>( 15 () => ExploreController(DI<SearchInteractor>())); 16 17 //usecase 18 DI.registerFactory<SearchInteractor>(() => SearchInteractor( 19 DI<MyRepository>(), DI<SearchPresenter>())); 20 21 //presenter 22 DI.registerFactory<SearchPresenter>(() => SearchPresenter()); 23}
あなたの回答
tips
プレビュー