没有包裹的话,就是空
RxInterface.proxy
T get value {
RxInterface.proxy?.addListener(subject);
return _value;
}
RxInterface.proxy?是空.
如果是obx包裹,则 RxInterface.proxy 有值。
就是ObxWidget 的observer:
ObxWidget:
final _observer = RxNotifier();
build:
Widget build(BuildContext context) =>
RxInterface.notifyChildren(_observer, widget.build);
1、注册回调
void initState() {
super.initState();
subs = _observer.listen(_updateTree, cancelOnError: false);
}
void _updateTree(_) {
if (mounted) {
setState(() {});
}
}
StreamSubscription<T> listen(
void Function(T) onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) =>
subject.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError ?? false,
);
LightSubscription<T> listen(void Function(T event) onData,
{Function? onError, void Function()? onDone, bool? cancelOnError}) {
final subs = LightSubscription<T>(
removeSubscription,
onPause: onPause,
onResume: onResume,
onCancel: onCancel,
)
..onData(onData)
..onError(onError)
..onDone(onDone)
..cancelOnError = cancelOnError;
addSubscription(subs);
onListen?.call();
return subs;
}
2、添加监听对象
T get value {
RxInterface.proxy?.addListener(subject);
return _value;
}
void addListener(GetStream<T> rxGetx) {
if (!_subscriptions.containsKey(rxGetx)) {
final subs = rxGetx.listen((data) {
if (!subject.isClosed) subject.add(data);
});
final listSubscriptions =
_subscriptions[rxGetx] ??= <StreamSubscription>[];
listSubscriptions.add(subs);
}
}
3、修改value
set value(T val) {
if (subject.isClosed) return;
sentToStream = false;
if (_value == val && !firstRebuild) return;
firstRebuild = false;
_value = val;
sentToStream = true;
subject.add(_value);
}
void add(T event) {
assert(!isClosed, 'You cannot add event to closed Stream');
_value = event;
_notifyData(event);
}
void _notifyData(T data) {
_isBusy = true;
for (final item in _onData!) {
if (!item.isPaused) {
item._data?.call(data);
}
}
_isBusy = false;
}
总结:
- state持有obs对象。
- controller 持有state,controller作用就是调用state。修改state中的obs对象值,达到刷新界面的作用。
- obs对象只有在obx包裹下,调用obs.value赋值才会刷新obx widget。否则只是读一个变量值而已。
- obx包裹的build方法中,需要调用obs对象,否则obx包裹没有作用。
思考:
父widget, controller。state
子widget,controller,state
父子widget共享state的同一个obs对象,当obs修改,父widget先刷新还是子widget先刷新? 还是只有父widget刷新?
mixin NotifyManager<T> {
void addListener(GetStream<T> rxGetx) {
if (!_subscriptions.containsKey(rxGetx)) {////不存在,创建
final subs = rxGetx.listen((data) {
if (!subject.isClosed) subject.add(data);
});
final listSubscriptions =
_subscriptions[rxGetx] ??= <StreamSubscription>[];
listSubscriptions.add(subs); ///listSubscriptions 多个,添加
}////存在了
}
}
_subscriptions[rxGetx] ??= <StreamSubscription>[];
bool containsKey(Object? key);
class RxNotifier<T> = RxInterface<T> with NotifyManager<T>;
final _observer = RxNotifier();