Getx State mixin
https://chornthorn.github.io/getx-docs/state-management/state-mixin/index
The Flutter GetX State Management
https://dev.to/gunathilakahashan10/getx-a-superior-state-management-in-flutter-4jcl
Getx + MVVM(Data Binding)구조 : 뷰(스크린)와 / [컨트롤러(뷰모델) <= 생산,저장(repository.dart) 데이타/상태 관리] 영역 분리.
1) 필요한 객체별 데이타모델(data class) 정의
2) 뷰페이지의 데이타 표시(Text,Listview)부는 데이타 바인딩 정의 후 대기(바인딩 변수가 초기화된 상태)
3) 웹서버 데이타를 http 호출, JSON수신받아 변수(메모리)에 저장 보관하는 repository.dart 데이타 저장소 준비
4) 컨트롤러에서 3)데이타 저장소 데이타를 메서드로 호출 이용 1)뷰페이지의 바인딩된 데이타에 대해 추가/변경/삭제
5) 1)뷰페이지에서 정의된 바인딩 변수값은 4)컨트롤러에 의해 3)저장소 데이타 변동시 실시간 반영되어 1)뷰페이지 UI 변동적용
※Getx 패키지에서 위 작업(Data Binding)을 모두 지원 해줌.
[데이타 로딩 다이얼로그 -> 결과수신 구현 예]
1) home_controller.dart 컨트롤러에 State mixin 구현(로딩중, 성공, 자료없음, 에러)
2) home.dart 뷰(스크린)에서 리스트뷰 위젯에 http 응답자료 수신하여 리스트뷰 완성하는 과정에
(로딩중 표출 -> 성공, 자료없음 또는 에러결과 수신 표출) 적용.
screens -> home.dart
class Home extends GetView<HomeController> {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: buildBuilderAppbarTitle(),
),
body: controller.obx(
(state) => _userInfoListWidget(),
// here you can put your custom loading indicator, but
onLoading: const Center(child: CircularProgressIndicator()),
// here you can set your No data message
onEmpty: const Center(child: Text('No data found')),
// here also you can set your own error widget
onError: (error) => Center(child:Text(error!)),
),
bottomNavigationBar: _bottomBtn(),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.updateUserInfo();
controller.updateTitle();
},
backgroundColor: Colors.green,
child: const Text("R"),
),
);
}
//ListView 데이타 바인딩
Widget _userInfoListWidget() {
return SingleChildScrollView(
child: Obx(
() => Column(
children: List.generate(
controller.userList.length,
(index) => _userInfoWidget(controller.userList[index]),
),
),
),
);
}
contorllers -> home_controller.dart
class HomeController extends GetxController with StateMixin {
late UserInfoModelRepository _userInfoModelRepository;
//RxList
RxList<UserInfoModel> userList = <UserInfoModel>[].obs;
//title default
RxString title = 'brus'.obs;
int count = 0;
@override
void onInit() {
super.onInit();
_userInfoModelRepository = UserInfoModelRepository();
//초기값은 empty상태
change(null, status: RxStatus.empty());
}
void loadUserInfo() async {
List<UserInfoModel> users;
//make status to loading
change(null, status: RxStatus.loading());
try {
//data Load... from (http) Server
users = await _userInfoModelRepository.getAllUserInfo();
//empty data check
if (users.isEmpty) {
change(null, status: RxStatus.empty());
} else {
//success
change(userList(users), status: RxStatus.success());
}
} catch (e) {
//error
change(null, status: RxStatus.error(e.toString()));
}
}
}