class DeviceUser {
String name;
int age;
List<Device> devices;
DeviceUser({
required this.name,
required this.age,
this.devices = [],
});
factory DeviceUser.empty() => DeviceUser(name: '', age: 0);
}
class Device {
String id;
String name;
Device({
required this.id,
required this.name,
});
factory Device.empty() => Device(id: '', name: '');
}
위와 같이 데이터가 주어진 경우 Bloc으로 Device데이터의 변화를 DeviceUser가 감지할 수 있도록 만들려고 한다.
Bloc에서는 스트림을 활용해서 이를 구현할 수 있는데, 이 글에서는 편의상 Cubit을 사용해 구현해보려고한다.
class DeviceUserCubit extends Cubit<DeviceUser>{
final List<StreamSubscription> _subscriptions = [];
DeviceUserCubit():super(DeviceUser.empty());
// 중요!!! -> Device의 상태가 변하는 것을 감지한다.
void addListener(Stream<Device> stream) {
StreamSubscription subscription = stream.listen((Device event) {
int index = state.devices.indexWhere((element) => element.id == event.id);
if (index != -1) {
List<Device> devices = state.devices.toList();
devices.replaceRange(index, index + 1, [event]);
emit(state.copyWith(devices: devices));
}
});
_subscriptions.add(subscription);
}
void cancelListener(int index) {
StreamSubscription subscription = _subscriptions[index];
subscription.cancel();
_subscriptions.removeAt(index);
}
}
class DeviceCubit extends Cubit<Device> {
DeviceCubit(DeviceUserCubit deviceUserCubit) : super(Device.empty()){
// 중요!!! -> DeviceCubit이 생성되는 순간 DeviceUserCubit과 스트림으로 연결된다.
deviceUserCubit.addListener(stream);
}
void updateDevice(Device device){
emit(device);
}
}
addListener 함수를 보면 DeviceCubit이 생성될 때 호출되는 것을 확인할 수 있다. 즉, DeviceCubit이 생성되는 즉시 DeviceCubit에 연결된 Device의 상태가 DeviceUserCubit으로 전달되는 것을 알 수 있다.