I am developing a flutter project using getx library.
I used binding to link getXView and controller, and I want to link it with SfCalendar's dataSource.
The code is as follows:
// CalendarView
class ICalendarView extends BaseView<ICalendarController> {
@override
PreferredSizeWidget? appBar(BuildContext context) {
return null;
}
@override
Widget body(BuildContext context) {
return Obx(
() => SfCalendar(
view: CalendarView.month,
dataSource: MeetingDataSource(controller.rxMeetingList),
monthViewSettings: const MonthViewSettings(
appointmentDisplayMode: MonthAppointmentDisplayMode.appointment,
showAgenda: true,
),
),
);
}
}
// calendar_controller
class ICalendarController extends BaseController {
final RxList<Meeting> rxMeetingList = RxList.empty();
@override
void onInit() {
rxMeetingList.addAll(_getDataSource());
}
List<Meeting> _getDataSource() {
final List<Meeting> meetings = <Meeting>[];
final DateTime today = DateTime.now();
final DateTime startTime = DateTime(today.year, today.month, today.day, 9);
final DateTime endTime = startTime.add(const Duration(hours: 2));
meetings.add(
Meeting('예시1', startTime, endTime, const Color(0xFF0F8644), false));
meetings.add(Meeting('예시2', startTime,
endTime.add(const Duration(hours: 2)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
return meetings;
}
}
// MeetingDataSource
class MeetingDataSource extends CalendarDataSource {
/// Creates a meeting data source, which used to set the appointment
/// collection to the calendar
MeetingDataSource(List<Meeting> source) {
appointments = source;
}
@override
DateTime getStartTime(int index) {
return _getMeetingData(index).from;
}
@override
DateTime getEndTime(int index) {
return _getMeetingData(index).to;
}
@override
String getSubject(int index) {
return _getMeetingData(index).eventName;
}
@override
Color getColor(int index) {
return _getMeetingData(index).background;
}
@override
bool isAllDay(int index) {
return _getMeetingData(index).isAllDay;
}
Meeting _getMeetingData(int index) {
final dynamic meeting = appointments![index];
late final Meeting meetingData;
if (meeting is Meeting) {
meetingData = meeting;
}
return meetingData;
}
}
It works fine when I use the Navigation tab to display the Calendar view after the initial build, but when I go to the Home view and return to the Calendar view, the following error occurs:
======== Exception caught by widgets library =======================================================
The following message was thrown building Obx(has builder, dirty, state: _ObxState#ed38f):
[Get] the improper use of a GetX has been detected.
You should only use GetX or Obx for the specific widget that will be updated.
If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
or insert them outside the scope that GetX considers suitable for an update
(example: GetX => HeavyWidget => variableObservable).
If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
Can you tell me what's wrong?
CodePudding user response:
I found the answer!
In previous code, I observed the calendar_controller's field "rxMeetingList" directly.
My solution was accessing calendar_controller's field "rxMeetingList" by getter/setter.
And, I changed super.onInit() code behind the initialization code.
The code is like below one.
class ICalendarController extends BaseController {
final RxList<Meeting> _rxMeetingList = RxList.empty();
@override
void onInit() {
_rxMeetingList.addAll(_getDataSource());
super.onInit();
}
List<Meeting> get meetingList => _rxMeetingList.toList();
List<Meeting> _getDataSource() {
final List<Meeting> meetings = <Meeting>[];
final DateTime today = DateTime.now();
final DateTime startTime = DateTime(today.year, today.month, today.day, 9);
final DateTime endTime = startTime.add(const Duration(hours: 2));
meetings.add(
Meeting('예시1', startTime, endTime, const Color(0xFF0F8644), false));
meetings.add(Meeting('예시2', startTime,
endTime.add(const Duration(hours: 2)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
meetings.add(Meeting('예시3', startTime,
endTime.add(const Duration(hours: 5)), const Color(0xFF0F8644), false));
return meetings;
}
}
class ICalendarView extends BaseView<ICalendarController> {
@override
PreferredSizeWidget? appBar(BuildContext context) {
return null;
}
@override
Widget body(BuildContext context) {
return Obx(
() => SfCalendar(
view: CalendarView.month,
dataSource: MeetingDataSource(controller.meetingList),
monthViewSettings: const MonthViewSettings(
appointmentDisplayMode: MonthAppointmentDisplayMode.appointment,
showAgenda: true,
),
),
);
}
}
CodePudding user response:
You should create your list like:
final RxList<Meeting> rxMeetingList = [].obs;
Adding the .obs makes your list observable for the widget: If you are seeing this error, you probably did not insert any observable variables into GetX/Obx or insert them outside the scope that GetX considers suitable for an update