Committed by
GitHub
Merge pull request #1134 from RafaRuiz/master
Create an Event Rx holder to call listeners when the same value is passed
Showing
2 changed files
with
69 additions
and
0 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. |
@@ -95,4 +95,38 @@ void main() { | @@ -95,4 +95,38 @@ void main() { | ||
95 | await Future.delayed(Duration.zero); | 95 | await Future.delayed(Duration.zero); |
96 | expect(count, 555); | 96 | expect(count, 555); |
97 | }); | 97 | }); |
98 | + | ||
99 | + test('Rx same value will not call the same listener when `call`', () async { | ||
100 | + var reactiveInteger = RxInt(2); | ||
101 | + var timesCalled = 0; | ||
102 | + reactiveInteger.listen((newInt) { | ||
103 | + timesCalled++; | ||
104 | + }); | ||
105 | + | ||
106 | + // we call 3 | ||
107 | + reactiveInteger.call(3); | ||
108 | + // then repeat twice | ||
109 | + reactiveInteger.call(3); | ||
110 | + reactiveInteger.call(3); | ||
111 | + | ||
112 | + await Future.delayed(Duration(milliseconds: 100)); | ||
113 | + expect(1, timesCalled); | ||
114 | + }); | ||
115 | + | ||
116 | + test('Rx same value will call the listener when `trigger`', () async { | ||
117 | + var reactiveInteger = RxInt(2); | ||
118 | + var timesCalled = 0; | ||
119 | + reactiveInteger.listen((newInt) { | ||
120 | + timesCalled++; | ||
121 | + }); | ||
122 | + | ||
123 | + // we call 3 | ||
124 | + reactiveInteger.trigger(3); | ||
125 | + // then repeat twice | ||
126 | + reactiveInteger.trigger(3); | ||
127 | + reactiveInteger.trigger(3); | ||
128 | + | ||
129 | + await Future.delayed(Duration(milliseconds: 100)); | ||
130 | + expect(3, timesCalled); | ||
131 | + }); | ||
98 | } | 132 | } |
-
Please register or login to post a comment