@@ -25,20 +25,23 @@ class ObservableList<T>
25
25
ListMixin <T >
26
26
implements
27
27
Listenable <ListChange <T >> {
28
- ObservableList ({ReactiveContext ? context, String ? name})
29
- : this ._wrap (context, _observableListAtom <T >(context, name), []);
28
+ ObservableList (
29
+ {ReactiveContext ? context, String ? name, EqualityComparer <T >? equals})
30
+ : this ._wrap (context, _observableListAtom <T >(context, name), [], equals);
30
31
31
32
ObservableList .of (Iterable <T > elements,
32
- {ReactiveContext ? context, String ? name})
33
+ {ReactiveContext ? context, String ? name, EqualityComparer < T > ? equals })
33
34
: this ._wrap (context, _observableListAtom <T >(context, name),
34
- List <T >.of (elements, growable: true ));
35
+ List <T >.of (elements, growable: true ), equals );
35
36
36
- ObservableList ._wrap (ReactiveContext ? context, this ._atom, this ._list)
37
+ ObservableList ._wrap (
38
+ ReactiveContext ? context, this ._atom, this ._list, this ._equals)
37
39
: _context = context ?? mainContext;
38
40
39
41
final ReactiveContext _context;
40
42
final Atom _atom;
41
43
final List <T > _list;
44
+ final EqualityComparer <T >? _equals;
42
45
43
46
List <T > get nonObservableInner => _list;
44
47
@@ -96,7 +99,7 @@ class ObservableList<T>
96
99
_context.conditionallyRunInAction (() {
97
100
final oldValue = _list[index];
98
101
99
- if (oldValue != value) {
102
+ if (_areEquals ( oldValue, value) ) {
100
103
_list[index] = value;
101
104
_notifyElementUpdate (index, value, oldValue);
102
105
}
@@ -167,10 +170,18 @@ class ObservableList<T>
167
170
}
168
171
169
172
@override
170
- Map <int , T > asMap () => ObservableMap ._wrap (_context, _list.asMap (), _atom);
173
+ Map <int , T > asMap () =>
174
+ ObservableMap ._wrap (_context, _list.asMap (), _atom, _equals);
171
175
172
176
@override
173
- List <R > cast <R >() => ObservableList ._wrap (_context, _atom, _list.cast <R >());
177
+ List <R > cast <R >([EqualityComparer <R >? equals]) => ObservableList ._wrap (
178
+ _context,
179
+ _atom,
180
+ _list.cast <R >(),
181
+ equals ??
182
+ (_equals != null
183
+ ? (R ? a, R ? b) => _equals !(a as T ? , b as T ? )
184
+ : null ));
174
185
175
186
@override
176
187
List <T > toList ({bool growable = true }) {
@@ -184,7 +195,7 @@ class ObservableList<T>
184
195
set first (T value) {
185
196
_context.conditionallyRunInAction (() {
186
197
final oldValue = _list.first;
187
- if (oldValue != value) {
198
+ if (_areEquals ( oldValue, value) ) {
188
199
_list.first = value;
189
200
_notifyElementUpdate (0 , value, oldValue);
190
201
}
@@ -376,7 +387,7 @@ class ObservableList<T>
376
387
for (var i = 0 ; i < _list.length; ++ i) {
377
388
final oldValue = oldList[i];
378
389
final newValue = _list[i];
379
- if (newValue != oldValue) {
390
+ if (_areEquals ( oldValue, newValue) ) {
380
391
changes.add (ElementChange (
381
392
index: i, oldValue: oldValue, newValue: newValue));
382
393
}
@@ -398,7 +409,7 @@ class ObservableList<T>
398
409
for (var i = 0 ; i < _list.length; ++ i) {
399
410
final oldValue = oldList[i];
400
411
final newValue = _list[i];
401
- if (newValue != oldValue) {
412
+ if (_areEquals ( oldValue, newValue) ) {
402
413
changes.add (ElementChange (
403
414
index: i, oldValue: oldValue, newValue: newValue));
404
415
}
@@ -456,6 +467,14 @@ class ObservableList<T>
456
467
457
468
_listeners.notifyListeners (change);
458
469
}
470
+
471
+ bool _areEquals (T ? a, T ? b) {
472
+ if (_equals != null ) {
473
+ return _equals !(a, b);
474
+ } else {
475
+ return equatable (a, b);
476
+ }
477
+ }
459
478
}
460
479
461
480
typedef ListChangeListener <TNotification > = void Function (
@@ -520,4 +539,4 @@ class ListChange<T> {
520
539
/// Used during testing for wrapping a regular `List<T>` as an `ObservableList<T>`
521
540
@visibleForTesting
522
541
ObservableList <T > wrapInObservableList <T >(Atom atom, List <T > list) =>
523
- ObservableList ._wrap (mainContext, atom, list);
542
+ ObservableList ._wrap (mainContext, atom, list, null );
0 commit comments