Showing
2 changed files
with
38 additions
and
44 deletions
@@ -199,6 +199,41 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { | @@ -199,6 +199,41 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { | ||
199 | fn(_value); | 199 | fn(_value); |
200 | subject.add(_value); | 200 | subject.add(_value); |
201 | } | 201 | } |
202 | + | ||
203 | + /// Following certain practices on Rx data, we might want to react to certain | ||
204 | + /// listeners when a value has been provided, even if the value is the same. | ||
205 | + /// At the moment, we ignore part of the process if we `.call(value)` with | ||
206 | + /// the same value since it holds the value and there's no real | ||
207 | + /// need triggering the entire process for the same value inside, but | ||
208 | + /// there are other situations where we might be interested in | ||
209 | + /// triggering this. | ||
210 | + /// | ||
211 | + /// For example, supposed we have a `int seconds = 2` and we want to animate | ||
212 | + /// from invisible to visible a widget in two seconds: | ||
213 | + /// RxEvent<int>.call(seconds); | ||
214 | + /// then after a click happens, you want to call a RxEvent<int>.call(seconds). | ||
215 | + /// By doing `call(seconds)`, if the value being held is the same, | ||
216 | + /// the listeners won't trigger, hence we need this new `trigger` function. | ||
217 | + /// This will refresh the listener of an AnimatedWidget and will keep | ||
218 | + /// the value if the Rx is kept in memory. | ||
219 | + /// Sample: | ||
220 | + /// ``` | ||
221 | + /// Rx<Int> secondsRx = RxInt(); | ||
222 | + /// secondsRx.listen((value) => print("$value seconds set")); | ||
223 | + /// | ||
224 | + /// secondsRx.call(2); // This won't trigger any listener, since the value is the same | ||
225 | + /// secondsRx.trigger(2); // This will trigger the listener independently from the value. | ||
226 | + /// ``` | ||
227 | + /// | ||
228 | + void trigger([T v]) { | ||
229 | + var firstRebuild = this.firstRebuild; | ||
230 | + value = v; | ||
231 | + // If it's not the first rebuild, the listeners have been called already | ||
232 | + // So we won't call them again. | ||
233 | + if (!firstRebuild) { | ||
234 | + subject.add(v); | ||
235 | + } | ||
236 | + } | ||
202 | } | 237 | } |
203 | 238 | ||
204 | /// Rx class for `bool` Type. | 239 | /// Rx class for `bool` Type. |
@@ -379,30 +414,6 @@ class Rx<T> extends _RxImpl<T> { | @@ -379,30 +414,6 @@ class Rx<T> extends _RxImpl<T> { | ||
379 | } | 414 | } |
380 | } | 415 | } |
381 | 416 | ||
382 | -/// Similar class to Rx<T> but this also will refresh the listeners if the same | ||
383 | -/// value has been provided. This is useful when maintaining a state with the | ||
384 | -/// same user = User("foo"). | ||
385 | -/// For example, supposed we have a `int seconds = 2` and we want to animate | ||
386 | -/// from invisible to visible a widget in two seconds: | ||
387 | -/// RxEvent<int>.call(seconds); | ||
388 | -/// then after a click happens, you want to call a RxEvent<int>.call(seconds). | ||
389 | -/// This will refresh the listener of an AnimatedWidget and will keep the value | ||
390 | -/// if the Rx is kept in memory. | ||
391 | -/// | ||
392 | -class RxEvent<T> extends Rx<T> { | ||
393 | - RxEvent([T initial]) : super(initial); | ||
394 | - | ||
395 | - void trigger([T v]) { | ||
396 | - var firstRebuild = this.firstRebuild; | ||
397 | - value = v; | ||
398 | - // If it's not the first rebuild, the listeners have been called already | ||
399 | - // So we won't call them again. | ||
400 | - if (!firstRebuild) { | ||
401 | - subject.add(v); | ||
402 | - } | ||
403 | - } | ||
404 | -} | ||
405 | - | ||
406 | extension StringExtension on String { | 417 | extension StringExtension on String { |
407 | /// Returns a `RxString` with [this] `String` as initial value. | 418 | /// Returns a `RxString` with [this] `String` as initial value. |
408 | RxString get obs => RxString(this); | 419 | RxString get obs => RxString(this); |
@@ -96,7 +96,7 @@ void main() { | @@ -96,7 +96,7 @@ void main() { | ||
96 | expect(count, 555); | 96 | expect(count, 555); |
97 | }); | 97 | }); |
98 | 98 | ||
99 | - test('Rx same value will not call the same listener', () async { | 99 | + test('Rx same value will not call the same listener when `call`', () async { |
100 | var reactiveInteger = RxInt(2); | 100 | var reactiveInteger = RxInt(2); |
101 | var timesCalled = 0; | 101 | var timesCalled = 0; |
102 | reactiveInteger.listen((newInt) { | 102 | reactiveInteger.listen((newInt) { |
@@ -113,8 +113,8 @@ void main() { | @@ -113,8 +113,8 @@ void main() { | ||
113 | expect(1, timesCalled); | 113 | expect(1, timesCalled); |
114 | }); | 114 | }); |
115 | 115 | ||
116 | - test('RxEvent same value will trigger the listener when trigger', () async { | ||
117 | - var reactiveInteger = RxEvent<int>(2); | 116 | + test('Rx same value will call the listener when `trigger`', () async { |
117 | + var reactiveInteger = RxInt(2); | ||
118 | var timesCalled = 0; | 118 | var timesCalled = 0; |
119 | reactiveInteger.listen((newInt) { | 119 | reactiveInteger.listen((newInt) { |
120 | timesCalled++; | 120 | timesCalled++; |
@@ -129,21 +129,4 @@ void main() { | @@ -129,21 +129,4 @@ void main() { | ||
129 | await Future.delayed(Duration(milliseconds: 100)); | 129 | await Future.delayed(Duration(milliseconds: 100)); |
130 | expect(3, timesCalled); | 130 | expect(3, timesCalled); |
131 | }); | 131 | }); |
132 | - | ||
133 | - test('RxEvent same value will not trigger the listener when call', () async { | ||
134 | - var reactiveInteger = RxEvent<int>(2); | ||
135 | - var timesCalled = 0; | ||
136 | - reactiveInteger.listen((newInt) { | ||
137 | - timesCalled++; | ||
138 | - }); | ||
139 | - | ||
140 | - // we call 3 | ||
141 | - reactiveInteger.call(3); | ||
142 | - // then repeat twice | ||
143 | - reactiveInteger.call(3); | ||
144 | - reactiveInteger.call(3); | ||
145 | - | ||
146 | - await Future.delayed(Duration(milliseconds: 100)); | ||
147 | - expect(1, timesCalled); | ||
148 | - }); | ||
149 | } | 132 | } |
-
Please register or login to post a comment