Flutter 아키텍처: 공급자 대 BLoC
게시 됨: 2020-04-17Flutter로 앱을 작성하면 아키텍처를 선택할 수 있는 좋은 기회가 생깁니다. 흔히 그렇듯이 "어떤 것을 선택해야 할까요?"라는 질문에 대한 가장 좋은 대답은 '에 따라 다릅니다. 그 답을 얻으면 프로그래밍 전문가를 찾았다고 확신할 수 있습니다.
이 기사에서는 모바일 애플리케이션에서 가장 많이 사용되는 화면을 살펴보고 가장 널리 사용되는 두 가지 Flutter 아키텍처인 Provider 및 BLoC 에서 구현합니다. 결과적으로 우리는 각 솔루션의 장단점을 배우게 될 것이며, 이는 다음 모듈이나 애플리케이션에 적합한 Flutter 아키텍처를 선택하는 데 도움이 될 것입니다.
Flutter 아키텍처에 대한 간략한 소개
Flutter 개발 프로젝트의 아키텍처를 선택하는 것은 매우 중요합니다. 주로 덜 일반적으로 사용되는 선언적 프로그래밍 패러다임을 다루고 있기 때문입니다. 이것은 네이티브 Android 또는 iOS 개발자가 익숙했던 상태를 관리하는 접근 방식을 완전히 바꾸어 코드를 필수적으로 작성합니다. 애플리케이션의 한 곳에서 사용할 수 있는 데이터를 다른 곳에서 얻기가 쉽지 않습니다. 현재 상태를 얻을 수 있는 트리의 다른 뷰에 대한 직접적인 참조가 없습니다.
Flutter에서 제공자란 무엇입니까?
이름에서 알 수 있듯이 Provider 는 현재 데이터 모델이 필요한 위치에 현재 데이터 모델을 제공하는 Flutter 아키텍처입니다. 여기에는 일부 데이터가 포함되어 있으며 변경이 발생하면 관찰자에게 알립니다. Flutter SDK에서 이 유형을 ChangeNotifier 라고 합니다. ChangeNotifier 유형의 객체를 다른 위젯에서 사용할 수 있으려면 ChangeNotifierProvider 가 필요합니다. 모든 하위 항목에 대해 관찰된 개체를 제공합니다. 현재 데이터를 수신할 수 있는 개체는 Consumer 이며, 후속 보기에 데이터를 제공하는 데 사용할 수 있는 빌드 함수의 매개변수에 ChangeNotifier 인스턴스가 있습니다.
Flutter에서 BLoC란 무엇입니까?
Business Logic Components는 MVP 또는 MVVM과 같은 모바일에서 널리 사용되는 솔루션과 훨씬 유사한 Flutter 아키텍처입니다. 비즈니스 논리 규칙에서 프레젠테이션 계층을 분리합니다. 이것은 Flutter가 강조하는 선언적 접근 방식의 직접적인 적용입니다. 즉 , UI = f(state) 입니다. BLoC는 사용자 인터페이스의 이벤트가 가는 곳입니다. 이 계층 내에서 주어진 이벤트에 비즈니스 규칙을 적용한 결과 BLoC는 특정 상태로 응답한 다음 UI로 돌아갑니다. 뷰 레이어가 새 상태를 받으면 현재 상태가 요구하는 바에 따라 뷰를 다시 빌드합니다.
Flutter 개발이 궁금하세요?
솔루션 보기Flutter에서 목록을 만드는 방법
스크롤 가능한 목록은 아마도 모바일 애플리케이션에서 가장 인기 있는 보기 중 하나일 것입니다. 따라서 여기서 올바른 Flutter 아키텍처를 선택하는 것이 중요할 수 있습니다. 이론적으로 목록 자체를 표시하는 것은 어렵지 않습니다. 예를 들어 각 요소에 대해 특정 작업을 수행하는 기능을 추가하면 상황이 더 복잡해집니다. 그러면 앱의 다른 위치에서 변경이 발생해야 합니다. 목록에서 각 요소를 선택할 수 있으며 선택한 각 요소는 다른 화면의 별도 목록에 표시됩니다.

따라서 선택한 요소를 새 화면에 표시할 수 있도록 저장해야 합니다. 또한 체크박스를 탭할 때마다 뷰를 다시 작성하여 실제로 체크/체크 해제를 표시해야 합니다.
목록 항목 모델은 매우 간단해 보입니다.
클래스 소셜 미디어 { 정수 아이디; 문자열 제목; 문자열 iconAsset; bool isFavorite; 소셜 미디어( {@필요한 this.id, @required this.title, @required this.iconAsset, this.isFavourite = false}); 무효 setFavourite(bool isFavourite) { this.isFavourite = isFavourite; } }
Provider로 목록을 만드는 방법
Provider 패턴에서는 위의 모델을 객체에 저장해야 합니다. 개체는 앱의 다른 위치에서 SocialMedia 에 액세스할 수 있도록 ChangeNotifier 를 확장해야 합니다.
클래스 SocialMediaModel 확장 ChangeNotifier { final List<SocialMedia> _socialMedia = [ /* 일부 소셜 미디어 개체 */ ]; UnmodifiableListView<SocialMedia> 즐겨찾기 가져오기 { 반환 UnmodifiableListView(_socialMedia.where((item) => item.isFavourite)); } UnmodifiableListView<SocialMedia>는 모든 { 반환 UnmodifiableListView(_socialMedia); } 무효 setFavourite(int itemId, bool isChecked) { _소셜 미디어 .firstwhere((항목) => item.id == itemId) .setFavourite(isChecked); 알림리스너(); }
뷰에서 다시 빌드해야 하는 이 객체의 모든 변경 사항은 notifyListeners() 를 사용하여 신호를 보내야 합니다. Flutter가 UI 조각을 다시 렌더링하도록 지시하는 setFavourite() 메서드의 경우 이 객체의 변경 사항을 관찰합니다.
이제 목록 생성으로 넘어갈 수 있습니다. ListView 를 요소로 채우려면 모든 요소의 목록을 저장하는 SocialMediaModel 개체에 접근해야 합니다. 두 가지 방법으로 수행할 수 있습니다.
- Provider.of<ModelType>(컨텍스트, 수신: false)
- 소비자
첫 번째는 관찰된 객체를 제공하고 객체에서 수행된 작업이 listen 매개변수를 사용하여 현재 위젯을 다시 빌드해야 하는지 여부를 결정할 수 있도록 합니다. 이 동작은 우리의 경우에 유용할 것입니다.
클래스 SocialMediaListScreen 확장 StatelessWidget { 소셜미디어목록화면(); @우세하다 위젯 빌드(BuildContext 컨텍스트) { var socialMedia = Provider.of<SocialMediaModel>(컨텍스트, 수신: false); 반환 목록보기( 어린이: socialMedia.all .map((항목) => CheckboxSocialMediaItem(항목: 항목)) .toList(), ); } }
모든 소셜 미디어 목록이 필요하지만 전체 목록을 다시 작성할 필요는 없습니다. 목록 항목 위젯이 어떻게 생겼는지 살펴보겠습니다.
클래스 CheckboxSocialMediaItem 확장 StatelessWidget { 최종 SocialMedia 항목; CheckboxSocialMediaItem({키 키, @required this.item}) : super(키: 키); @우세하다 위젯 빌드(BuildContext 컨텍스트) { 반환 패딩( 패딩: const EdgeInsets.all(Dimens.paddingDefault), 자식: 행( 어린이들: [ 소비자<소셜미디어모델>( 빌더: (컨텍스트, 모델, 자식) { 반환 체크박스( 값: item.isFavourite, onChanged: (isChecked) => model.setFavourite(item.id, isChecked), ); }, ), 소셜미디어아이템( 항목: 항목, ) ], ), ); } }
체크박스 값의 변화를 듣고 체크 상태에 따라 모델을 업데이트합니다. 체크박스 값 자체는 데이터 모델의 속성을 사용하여 설정됩니다. 이것은 선택 후 모델이 isFavourite 필드를 true 로 변경함을 의미합니다. 그러나 확인란을 다시 빌드할 때까지 보기에 이 변경 사항이 표시되지 않습니다. 여기에서 Consumer 객체가 도움이 됩니다. 관찰된 객체를 제공하고 모델의 변경 사항에 대한 정보를 받은 후 그의 모든 자손을 재구축합니다.
불필요한 다시 빌드 보기를 피하기 위해 위젯을 업데이트해야 하는 위치에만 Consumer 를 배치하는 것이 좋습니다. 예를 들어 확인란 선택이 항목 제목 변경과 같은 추가 작업을 트리거하는 경우 소비자 는 제목 표시를 담당하는 위젯의 부모가 되기 위해 위젯 트리에서 상위로 이동해야 합니다. . 그렇지 않으면 제목 보기가 업데이트되지 않습니다.
즐겨찾는 소셜 미디어 화면을 만드는 것도 비슷할 것입니다. Provider 를 사용하여 즐겨찾는 항목 목록을 가져옵니다.
클래스 FavoritesListScreen 확장 StatelessWidget { 즐겨찾기 목록 화면(); @우세하다 위젯 빌드(BuildContext 컨텍스트) { var list = Provider.of<SocialMediaModel>(context, listen: false).favorites; 반환 목록보기( 어린이: 목록 .map((항목) => 패딩( 패딩: const EdgeInsets.all(Dimens.paddingDefault), 자식: SocialMediaItem(항목: 항목))) .toList(), ); } }
build 메소드가 호출되면 제공자 는 즐겨찾는 소셜 미디어의 현재 목록을 반환합니다.
BLoC으로 목록을 만드는 방법
우리의 간단한 애플리케이션에는 지금까지 두 개의 화면이 있습니다. 그들 각각은 고유 한 BLoC 개체를 갖습니다. 단, 메인 화면에서 선택한 항목은 즐겨찾는 소셜 미디어 목록에 표시됩니다. 따라서 어떻게든 체크박스 선택 이벤트를 화면 외부로 전송해야 합니다. 해결책은 많은 화면의 상태에 영향을 미치는 이벤트를 처리할 추가 BLoC 개체를 만드는 것입니다. 글로벌 BLoC 라고 합시다. 그러면 개별 화면에 할당된 BLoC 개체가 글로벌 BLoC 상태의 변경 사항을 수신하고 그에 따라 응답합니다.
BLoC 객체를 생성하기 전에 먼저 뷰가 BLoC 레이어에 보낼 수 있는 이벤트와 응답할 상태에 대해 생각해야 합니다. 글로벌 BLoC 의 경우 이벤트 및 상태는 다음과 같습니다.
추상 클래스 SocialMediaEvent {} 클래스 CheckboxChecked는 SocialMediaEvent를 확장합니다. { 최종 bool isChecked; 최종 정수 itemId; CheckboxChecked(this.isChecked, this.itemId); } 추상 클래스 SocialMediaState {} 클래스 ListPresented는 SocialMediaState를 확장합니다. { 최종 목록<SocialMedia> 목록; ListPresented(this.list); }
CheckboxChecked 이벤트는 전역 BLoC 에 있어야 합니다. 한 화면이 아닌 여러 화면의 상태에 영향을 미치기 때문입니다. 상태와 관련하여 목록을 표시할 준비가 된 상태가 있습니다. 글로벌 BLoC 관점에서는 더 많은 상태를 생성할 필요가 없습니다. 두 화면 모두 목록을 표시해야 하며 특정 화면 전용 BLoC 가 이를 처리해야 합니다. 글로벌 BLoC 자체의 구현은 다음과 같습니다.
클래스 SocialMediaBloc extends Bloc<SocialMediaEvent, SocialMediaState> { 최종 SimpleSocialMediaRepository 저장소; 소셜미디어블록(this.repository); @우세하다 SocialMediaState get initialState => ListPresented(repository.getSocialMedia); @우세하다 Stream<SocialMediaState> mapEventToState(SocialMediaEvent 이벤트) async* { if (이벤트가 CheckboxChecked임) { yield _mapCheckboxCheckedToState(이벤트); } } SocialMediaState _mapCheckboxCheckedToState(CheckboxChecked 이벤트) { 최종 updatedList = (ListPresented로 상태).list; 업데이트된 목록 .firstwhere((항목) => item.id == event.itemId) .setFavourite(event.isChecked); 반환 ListPresented(업데이트된 목록); } }
초기 상태는 ListPresented 입니다. 우리는 이미 저장소에서 데이터를 수신했다고 가정합니다. 하나의 이벤트인 CheckboxChecked 에만 응답하면 됩니다. 따라서 setFavourite 메서드를 사용하여 선택한 요소를 업데이트하고 ListPresented 상태로 래핑된 새 목록을 보냅니다.
이제 체크박스를 테이핑할 때 CheckboxChecked 이벤트를 보내야 합니다. 이렇게 하려면 onChanged 콜백을 첨부할 수 있는 곳에 SocialMediaBloc 의 인스턴스가 필요합니다. BlocProvider 를 사용하여 이 인스턴스를 얻을 수 있습니다. 위에서 설명한 패턴의 Provider 와 유사해 보입니다. 이러한 BlocProvider 가 작동하려면 위젯 트리의 상위에서 원하는 BLoC 객체를 초기화해야 합니다. 이 예에서는 main 메서드에서 수행됩니다.
무효 메인() => runApp(BlocProvider( 생성: (문맥) { 반환 SocialMediaBloc(SimpleSocialMediaRepository()); }, 자식: ArchitecturesSampleApp()));
덕분에 기본 목록 코드에서 BlocProvider.of() 를 사용하여 BLoC 를 쉽게 호출하고 add 메서드를 사용하여 이벤트를 보낼 수 있습니다.
클래스 SocialMediaListScreen 확장 StatefulWidget { _SocialMediaListState createState() => _SocialMediaListState(); } 클래스 _SocialMediaListState는 State<SocialMediaListScreen>을 확장합니다. { @우세하다 위젯 빌드(BuildContext 컨텍스트) { 반환 BlocBuilder<SocialMediaListBloc, SocialMediaListState>( 빌더: (컨텍스트, 상태) { if(상태가 MainListLoaded임) { 반환 목록보기( 어린이: state.socialMedia .map((항목) => CheckboxSocialMediaItem( 항목: 항목, onCheckboxChanged: (isChecked) => BlocProvider.of<SocialMediaBloc>(컨텍스트) .add(CheckboxChecked(isChecked, item.id)), )) .toList(), ); } 또 다른 { 반환 센터(자식: Text(Strings.emptyList)); } }, ); } }
우리는 이미 BLoC 에 대한 CheckboxChecked 이벤트 전파를 가지고 있으며 BLoC 가 그러한 이벤트에 어떻게 응답할지 또한 알고 있습니다. 그러나 실제로... 체크박스가 이미 선택된 상태에서 목록을 다시 작성하게 하는 원인은 무엇입니까? Global BLoC 는 화면에 할당된 개별 BLoC 개체에 의해 처리되기 때문에 목록 상태 변경을 지원하지 않습니다. 해결 방법은 앞에서 언급한 글로벌 BLoC 를 수신하여 상태를 변경하고 이 상태에 따라 응답하는 것입니다. 아래는 확인란이 있는 주요 소셜 미디어 목록 전용 BLoC 입니다.

클래스 SocialMediaListBloc 확장 블록<SocialMediaListEvent, SocialMediaListState> { 최종 SocialMediaBloc 메인 블록; SocialMediaListBloc({@required this.mainBloc}) { mainBloc.listen((상태) { if(상태가 ListPresented임) { 추가(화면 시작(state.list)); } }); } @우세하다 SocialMediaListState get initialState => MainListEmpty(); @우세하다 스트림<SocialMediaListState> mapEventToState( SocialMediaListEvent 이벤트) async* { 스위치(event.runtimeType) { 케이스 화면 시작: yield MainListLoaded((ScreenStart로 이벤트).list); 부서지다; } } }
SocialMediaBloc 이 ListPresented 상태를 반환하면 SocialMediaListBloc 에 알림이 전송됩니다. ListPresented 는 목록을 전달합니다. 체크박스로 항목을 확인하는 업데이트된 정보가 포함된 항목입니다.
마찬가지로 즐겨 찾는 소셜 미디어 화면 전용 BLoC 를 만들 수 있습니다.
클래스 FavouritesListBloc extends Bloc<FavouritesListEvent, FavouritesListSate> { 최종 SocialMediaBloc 메인 블록; 즐겨찾기 목록 블록({@required this.mainBloc}) { mainBloc.listen((상태) { if(상태가 ListPresented임) { 추가(즐겨찾기 화면 시작(state.list)); } }); } @우세하다 FavoritesListSate get initialState => FavoritesListEmpty(); @우세하다 Stream<FavouritesListSate> mapEventToState(FavouritesListEvent 이벤트) async* { if (이벤트가 즐겨찾기 화면 시작임) { var 즐겨 찾기 목록 = event.list.where((item) => item.isFavourite).toList(); 수익률 FavoritesListLoaded(즐겨찾기 목록); } } }
전역 BLoC 에서 상태를 변경하면 현재 목록과 함께 FavoritesScreenStart 이벤트가 발생합니다. 그러면 즐겨찾기로 표시된 항목이 필터링되어 해당 목록이 화면에 표시됩니다.
Flutter에서 많은 필드가 있는 양식을 만드는 방법
긴 형식은 특히 요구 사항이 다른 유효성 검사 변형을 가정하거나 텍스트를 입력한 후 화면의 일부 변경 사항을 가정하는 경우 까다로울 수 있습니다. 예제 화면에는 여러 필드와 "NEXT" 버튼으로 구성된 양식이 있습니다. 필드는 자동으로 유효성을 검사하고 양식이 완전히 유효해질 때까지 버튼이 비활성화됩니다. 버튼을 클릭하면 양식에 입력한 데이터가 있는 새 화면이 열립니다.
버튼 상태를 올바르게 설정하려면 각 필드의 유효성을 검사하고 전체 양식 수정을 확인해야 합니다. 그런 다음 수집된 데이터는 다음 화면을 위해 저장해야 합니다.

Provider를 사용하여 많은 필드가 있는 양식을 만드는 방법
우리 애플리케이션에서는 개인 정보 화면 전용인 두 번째 ChangeNotifier 가 필요합니다. 따라서 ChangeNotifier 개체 목록을 제공하는 MultiProvider 를 사용할 수 있습니다. MultiProvider 의 모든 자손이 사용할 수 있습니다.
클래스 ArchitectureSampleApp 확장 StatelessWidget { 최종 SimpleSocialMediaRepository 저장소; ArchitecturesSampleApp({키 키, this.repository}) : super(키: 키); @우세하다 위젯 빌드(BuildContext 컨텍스트) { 반환 다중 공급자( 공급자: [ ChangeNotifierProvider<소셜미디어모델>( 생성: (컨텍스트) => SocialMediaModel(리포지토리), ), ChangeNotifierProvider<PersonalDataNotifier>( 생성: (컨텍스트) => PersonalDataNotifier(), ) ], 자식: MaterialApp( 제목: Strings.architecturesSampleApp, debugShowCheckedModeBanner: 거짓, 홈: 시작 화면(), 경로: <문자열, WidgetBuilder>{ Routes.socialMedia: (컨텍스트) => SocialMediaScreen(), Routes.favorites: (컨텍스트) => 즐겨찾기 화면(), Routes.personalDataForm: (컨텍스트) => PersonalDataScreen(), Routes.personalDataInfo: (컨텍스트) => PersonalDataInfoScreen() }, ), ); } }
이 경우 PersonalDataNotifier 는 비즈니스 논리 계층으로 작동합니다. 그는 필드의 유효성을 검사하고, 업데이트를 위해 데이터 모델에 액세스하고, 보기가 의존하는 필드를 업데이트합니다.
양식 자체는 속성 유효성 검사기 를 사용하여 자동으로 유효성 검사를 첨부하고 onSaved 콜백을 사용하여 양식의 데이터를 모델에 저장할 수 있는 Flutter의 매우 멋진 API입니다. 검증 규칙을 PersonalDataNotifier 에 위임하고 양식이 올바르면 입력된 데이터를 전달합니다.
이 화면에서 가장 중요한 것은 유효성 검사 결과에 따라 각 필드의 변경 사항을 듣고 버튼을 활성화 또는 비활성화하는 것입니다. Form 객체에서 onChange 콜백을 사용할 것입니다. 여기에서 먼저 유효성 검사 상태를 확인한 다음 PersonalDataNotifier 에 전달합니다.
형태( 키: _formKey, 자동 검증: 참, onChanged: () => _onFormChanged(personalDataNotifier), 어린이: 무효 _onFormChanged(PersonalDataNotifier PersonalDataNotifier) { var isValid = _formKey.currentState.validate(); PersonalDataNotifier.onFormChanged(isValid); }
PersonalDataNotifier 에서 isFormValid 변수를 준비합니다. 이를 수정하고( notifyListeners() 호출하는 것을 잊지 마세요) 뷰에서 해당 값에 따라 버튼 상태를 변경합니다. Listen : true 매개변수를 사용하여 Notifier 인스턴스를 얻는 것을 기억하십시오. 그렇지 않으면 뷰가 다시 빌드되지 않고 버튼 상태가 변경되지 않은 상태로 유지됩니다.
var PersonalDataNotifier = Provider.of<PersonalDataNotifier>(컨텍스트, 수신: true);
실제로 뷰를 다시 로드할 필요가 없는 다른 위치에서 PersonalDataNotifier 를 사용한다는 사실을 감안할 때 위의 라인은 최적이 아니며 listen 매개변수를 false 로 설정해야 합니다. 다시 로드하고 싶은 것은 버튼뿐이므로 클래식 Consumer 에서 래핑할 수 있습니다.
소비자<PersonalDataNotifier>( 빌더: (컨텍스트, 알리미, 자식) { RaisedButton( 자식: 텍스트(Strings.addressNext), onPressed: 알림자.isFormValid ? /* 버튼이 활성화되었을 때의 동작 */ : 없는, 색상: Colors.blue, disabledColor: Colors.grey, ); }, )
덕분에 알리미를 사용할 때마다 다른 구성 요소를 강제로 다시 로드하지 않아도 됩니다.
개인 데이터를 표시하는 보기에서 더 이상 문제가 발생하지 않습니다. PersonalDataNotifier 에 액세스할 수 있으며 여기에서 업데이트된 모델을 다운로드할 수 있습니다.
BLoC를 사용하여 많은 필드가 있는 양식을 만드는 방법
이전 화면에서는 두 개의 BLoC 개체가 필요했습니다. 따라서 다른 "이중 화면"을 추가하면 모두 4개가 됩니다. Provider 의 경우와 마찬가지로 거의 동일하게 작동하는 MultiBlocProvider 로 처리할 수 있습니다.
무효 메인() => runApp( MultiBlocProvider(제공자: [ 블록 제공자( 생성: (컨텍스트) => SocialMediaBloc(SimpleSocialMediaRepository()), ), 블록 제공자( 생성: (컨텍스트) => SocialMediaListBloc( mainBloc: BlocProvider.of<SocialMediaBloc>(context))), 블록 제공자( 생성: (컨텍스트) => PersonalDataBloc(), ), 블록 제공자( 생성: (컨텍스트) => PersonalDataInfoBloc( mainBloc: BlocProvider.of<PersonalDataBloc>(컨텍스트)), ) ], 자식: ArchitecturesSampleApp()), );
BLoC 패턴과 마찬가지로 가능한 상태와 동작부터 시작하는 것이 가장 좋습니다.
추상 클래스 PersonalDataState {} 클래스 NextButtonDisabled는 PersonalDataState {}를 확장합니다. 클래스 NextButtonEnabled 확장 PersonalDataState {} 클래스 InputFormCorrect는 PersonalDataState를 확장합니다. { 최종 PersonalData 모델; InputFormCorrect(this.model); }
이 화면에서 변경되는 것은 버튼 상태입니다. 따라서 별도의 상태가 필요합니다. 또한 InputFormCorrect 상태를 사용하면 양식에서 수집한 데이터를 보낼 수 있습니다.
추상 클래스 PersonalDataEvent {} 클래스 FormInputChanged는 PersonalDataEvent를 확장합니다. { 최종 bool isValid; FormInputChanged(this.isValid); } 클래스 FormCorrect는 PersonalDataEvent를 확장합니다. { 최종 개인 데이터 양식데이터; FormCorrect(this.formData); }
양식의 변경 사항을 수신하는 것이 중요하므로 FormInputChanged 이벤트가 발생합니다. 양식이 정확하면 FormCorrect 이벤트가 전송됩니다.
유효성 검사와 관련하여 공급자와 비교하면 여기에 큰 차이가 있습니다. 모든 유효성 검사 로직을 BLoC 계층에 포함하려면 각 필드에 대해 많은 이벤트가 있어야 합니다. 또한 많은 상태에서 보기에 유효성 검사 메시지를 표시해야 합니다.
이것은 물론 가능하지만 이점을 사용하는 대신 TextFormField API와 싸우는 것과 같습니다. 따라서 명확한 이유가 없으면 뷰 레이어에 유효성 검사를 남겨둘 수 있습니다.
버튼 상태는 BLoC 에서 보기로 보낸 상태에 따라 달라집니다.
BlocBuilder<PersonalDataBloc, PersonalDataState>( 빌더: (컨텍스트, 상태) { RaisedButton( 자식: 텍스트(Strings.addressNext), onPressed: 상태가 NextButtonEnabled입니다. ? /* 버튼이 활성화되었을 때의 동작 */ : 없는, 색상: Colors.blue, disabledColor: Colors.grey, ); })
PersonalDataBloc 의 상태에 대한 이벤트 처리 및 매핑은 다음과 같습니다.
@우세하다 Stream<PersonalDataState> mapEventToState(PersonalDataEvent 이벤트) async* { if(이벤트가 FormCorrect임) { 수율 InputFormCorrect(event.formData); } else if(이벤트가 FormInputChanged임) { mapFormInputChangedToState(이벤트)를 생성합니다. } } PersonalDataState mapFormInputChangedToState(FormInputChanged 이벤트) { if (event.isValid) { 반환 NextButtonEnabled(); } 또 다른 { 반환 NextButtonDisabled(); } }
개인정보를 요약한 화면은 앞의 예시와 비슷합니다. 이 화면에 부착된 BLoC 는 양식 화면의 BLoC 에서 모델 정보를 검색합니다.
클래스 PersonalDataInfoBloc 확장 블록<PersonalDataInfoEvent, PersonalDataInfoState> { 최종 PersonalDataBloc mainBloc; PersonalDataInfoBloc({@required this.mainBloc}) { mainBloc.listen((상태) { if(상태가 InputFormCorrect임) { 추가(개인 데이터 정보 화면 시작(상태 모델)); } }); } @우세하다 PersonalDataInfoState get initialState => InfoEmpty(); @우세하다 Stream<PersonalDataInfoState> mapEventToState(PersonalDataInfoEvent 이벤트) async* { if(이벤트는 PersonalDataInfoScreenStart임) { yield InfoLoaded(event.model); } } }
Flutter 아키텍처: 기억해야 할 메모
위의 예는 두 아키텍처 사이에 분명한 차이점이 있음을 보여주기에 충분합니다. BLoC 는 뷰 레이어를 비즈니스 로직과 아주 잘 분리합니다. 이것은 더 나은 재사용성과 테스트 가능성을 수반합니다. 간단한 경우를 처리하려면 Provider 보다 더 많은 코드를 작성해야 하는 것 같습니다. 아시다시피 이 경우 Flutter 아키텍처는 애플리케이션의 복잡성이 증가함에 따라 더욱 유용해집니다.
비즈니스를 위한 미래 지향적인 앱을 구축하고 싶으십니까?
연락하자또한 공급자 는 UI를 논리와 잘 분리하고 각 사용자 상호 작용에 대해 별도의 상태를 강제로 생성하지 않으므로 간단한 경우를 처리하기 위해 많은 양의 코드를 작성할 필요가 없는 경우가 많습니다. 그러나 이것은 더 복잡한 경우에 문제를 일으킬 수 있습니다.
전체 프로젝트를 확인하려면 여기를 클릭하십시오.