-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
watch.dart
89 lines (78 loc) · 2.77 KB
/
watch.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import 'package:flutter/material.dart';
import 'package:katana_scoped/katana_scoped.dart';
/// Provides an extended method for [Ref] to monitor [ChangeNotifier].
///
/// [ChangeNotifier]の監視を行うための[Ref]用の拡張メソッドを提供します。
extension RefWatchExtensions on Ref {
/// You can monitor it by passing a [callback] that returns a [ChangeNotifier].
///
/// When [ChangeNotifier.notifyListeners] is executed, the update is notified and the associated widget is redrawn.
///
/// If [keys] is different from the previous value, [callback] is executed again and the new [ChangeNotifier] is saved.
///
/// If [name] is specified, it is saved as a separate type. If [keys] is changed, the previous state is discarded, but if [name] is changed, it is kept as a separate state.
///
/// [ChangeNotifier]を返す[callback]を渡すとそれを監視することができます。
///
/// [ChangeNotifier.notifyListeners]が実行されると更新が通知され、関連するウィジェットが再描画されます。
///
/// [keys]が前の値と違う場合再度[callback]が実行され、新しい[ChangeNotifier]が保存されます。
///
/// [name]を指定すると別のタイプとして保存されます。[keys]を変えた場合は以前の状態は破棄されますが、[name]を変えた場合は別々の状態として保持されます。
T watch<T extends Listenable>(
T Function() callback, {
List<Object> keys = const [],
String? name,
}) {
return getScopedValue<T, _WatchValue<T>>(
() => _WatchValue<T>(callback: callback, keys: keys),
listen: true,
name: name,
);
}
}
@immutable
class _WatchValue<T extends Listenable> extends ScopedValue<T> {
const _WatchValue({
required this.callback,
required this.keys,
});
final T Function() callback;
final List<Object> keys;
@override
ScopedValueState<T, ScopedValue<T>> createState() => _WatchValueState<T>();
}
class _WatchValueState<T extends Listenable>
extends ScopedValueState<T, _WatchValue<T>> {
_WatchValueState();
late T _value;
@override
void initValue() {
super.initValue();
_value = value.callback();
_value.addListener(_handledOnUpdate);
}
void _handledOnUpdate() {
setState(() {});
}
@override
void didUpdateValue(_WatchValue<T> oldValue) {
super.didUpdateValue(oldValue);
if (!equalsKeys(value.keys, oldValue.keys)) {
_value.removeListener(_handledOnUpdate);
_value = value.callback();
_value.addListener(_handledOnUpdate);
}
}
@override
void dispose() {
super.dispose();
final val = _value;
_value.removeListener(_handledOnUpdate);
if (val is ChangeNotifier) {
val.dispose();
}
}
@override
T build() => _value;
}