Showing
10 changed files
with
216 additions
and
151 deletions
| 1 | -## [3.25.0] | 1 | +## [3.25.0] - Big update |
| 2 | +- Added [FullLifeCycleController] - A GetxController capable of observing all the life cycles of your application. FullLifeCycleController has the life cycles: | ||
| 3 | + * onInit: called when the controller enters the application's memory | ||
| 4 | + * onReady: called after onInit, when build method from widget relationed to controller is done. | ||
| 5 | + * onClose: called when controller is deleted from memory. | ||
| 6 | + * onPaused: called when the application is not currently visible to the user, and running in the background. | ||
| 7 | + * onInactive: called when the application is in an inactive state and is not receiving user input, when the user receives a call, for example | ||
| 8 | + * onResumed: The application is now visible and in the foreground | ||
| 9 | + * onDetached: The application is still hosted on a flutter engine but is detached from any host views. | ||
| 10 | + * didChangeMetrics: called when the window size is changed | ||
| 11 | +- Added SuperController, a complete life circle controller with StateMixin | ||
| 12 | +- Improve Iterable Rx Api. Now, you can to use dart List, Map and Set as reactive, like: List<String> names = <String>['juan', 'pedro', 'maria'].obs; | ||
| 13 | +- Added [reload] and [reloadAll] methods to reload your Controller to original values | ||
| 14 | +- Added assign and assignAll extensions to default dart List | ||
| 15 | +- Added parameters options from Get.toNamed, Get.offNamed, and Get.offAllNamed (@enghitalo) | ||
| 16 | +- Improve Rx disposal logic to completely prevent memory leaks | ||
| 17 | +- Improve Capitalize methods from GetUtils (@eduardoflorence) | ||
| 18 | +- Prevent a close snackbar from close a Screen with double tap (@eduardoflorence) | ||
| 19 | +- Includes GetLifeCycleBase mixin on delete/dispose (@saviogrossi) | ||
| 20 | +- Added internacionalization example to sample app (@rodriguesJeff) | ||
| 21 | +- Added headers to Graphql query and mutation(@asalvi0) | ||
| 22 | +- Added translation with parameter extension (@CpdnCristiano) | ||
| 23 | +- Added Get.parameter access to Middleware (@eduardoflorence) | ||
| 24 | +- Fix RxBool typo (@emanuelmutschlechner) | ||
| 25 | +- Added Filter to GetBuilder | ||
| 26 | +- Added debouce to GetBuilder update | ||
| 27 | +- Added ability to insert an Enum, class, or type of an object as a GetBuilder's Id | ||
| 28 | +- Improve upload time from GetConnect | ||
| 29 | +- Create minified version to DartPad(@roipeker) | ||
| 30 | +- Suggested to use `Get.to(() => Page())` instead of `Get.to(Page())`. | ||
| 31 | +- Fix and improve docs: @unacorbatanegra, @lsm, @nivisi, @ThinkDigitalSoftware, @martwozniak, @UsamaElgendy, @@DominusKelvin, @jintak0401, | ||
| 32 | + | ||
| 2 | 33 | ||
| 3 | ## [3.24.0] | 34 | ## [3.24.0] |
| 4 | - GetWidget has been completely redesigned. | 35 | - GetWidget has been completely redesigned. |
| @@ -7,4 +7,4 @@ const Map<String, String> en_US = { | @@ -7,4 +7,4 @@ const Map<String, String> en_US = { | ||
| 7 | 'total_infecteds': 'Total Infecteds', | 7 | 'total_infecteds': 'Total Infecteds', |
| 8 | 'details': 'Details', | 8 | 'details': 'Details', |
| 9 | 'total_recovered': 'Total Recovered', | 9 | 'total_recovered': 'Total Recovered', |
| 10 | -}; | ||
| 10 | +}; |
| @@ -42,8 +42,9 @@ class CountryView extends GetView<HomeController> { | @@ -42,8 +42,9 @@ class CountryView extends GetView<HomeController> { | ||
| 42 | "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"), | 42 | "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"), |
| 43 | ), | 43 | ), |
| 44 | title: Text(country.country), | 44 | title: Text(country.country), |
| 45 | - subtitle: | ||
| 46 | - Text('total_infecteds'.tr +' ${country.totalConfirmed}'), | 45 | + subtitle: Text( |
| 46 | + // ignore: lines_longer_than_80_chars | ||
| 47 | + '${'total_infecteds'.tr}${' ${country.totalConfirmed}'}'), | ||
| 47 | ); | 48 | ); |
| 48 | }), | 49 | }), |
| 49 | ), | 50 | ), |
example/test/widget_test.dart
deleted
100644 → 0
| 1 | -// This is a basic Flutter widget test. | ||
| 2 | -// | ||
| 3 | -// To perform an interaction with a widget in your test, use the WidgetTester | ||
| 4 | -// utility that Flutter provides. For example, you can send tap and scroll | ||
| 5 | -// gestures. You can also use WidgetTester to find child widgets in the widget | ||
| 6 | -// tree, read text, and verify that the values of widget properties are correct. | ||
| 7 | - | ||
| 8 | -import 'package:flutter/material.dart'; | ||
| 9 | -import 'package:flutter_test/flutter_test.dart'; | ||
| 10 | - | ||
| 11 | -import '../lib/main.dart'; | ||
| 12 | - | ||
| 13 | -void main() { | ||
| 14 | - testWidgets('Counter increments smoke test', (WidgetTester tester) async { | ||
| 15 | - // Build our app and trigger a frame. | ||
| 16 | - await tester.pumpWidget(MyApp()); | ||
| 17 | - | ||
| 18 | - // Verify that our counter starts at 0. | ||
| 19 | - expect(find.text('0'), findsOneWidget); | ||
| 20 | - expect(find.text('1'), findsNothing); | ||
| 21 | - | ||
| 22 | - // Tap the '+' icon and trigger a frame. | ||
| 23 | - await tester.tap(find.byIcon(Icons.add)); | ||
| 24 | - await tester.pump(); | ||
| 25 | - | ||
| 26 | - // Verify that our counter has incremented. | ||
| 27 | - expect(find.text('0'), findsNothing); | ||
| 28 | - expect(find.text('1'), findsOneWidget); | ||
| 29 | - }); | ||
| 30 | -} |
| @@ -50,41 +50,6 @@ class GetInstance { | @@ -50,41 +50,6 @@ class GetInstance { | ||
| 50 | /// non-singleton instances. | 50 | /// non-singleton instances. |
| 51 | static final Map<String, HashSet<Function>> _routesByCreate = {}; | 51 | static final Map<String, HashSet<Function>> _routesByCreate = {}; |
| 52 | 52 | ||
| 53 | - /// Creates a new Instance<S> lazily from the [<S>builder()] callback. | ||
| 54 | - /// | ||
| 55 | - /// The first time you call [Get.find()], the [builder()] callback will create | ||
| 56 | - /// the Instance and persisted as a Singleton (like you would | ||
| 57 | - /// use [Get.put()]). | ||
| 58 | - /// | ||
| 59 | - /// Using [Get.smartManagement] as [SmartManagement.keepFactory] has | ||
| 60 | - /// the same outcome as using [fenix:true] : | ||
| 61 | - /// The internal register of [builder()] will remain in memory to recreate | ||
| 62 | - /// the Instance if the Instance has been removed with [Get.delete()]. | ||
| 63 | - /// Therefore, future calls to [Get.find()] will return the same Instance. | ||
| 64 | - /// | ||
| 65 | - /// If you need to make use of GetxController's life-cycle | ||
| 66 | - /// ([onInit(), onStart(), onClose()]) [fenix] is a great choice to mix with | ||
| 67 | - /// [GetBuilder()] and [GetX()] widgets, and/or [GetMaterialApp] Navigation. | ||
| 68 | - /// | ||
| 69 | - /// You could use [Get.lazyPut(fenix:true)] in your app's [main()] instead | ||
| 70 | - /// of [Bindings()] for each [GetPage]. | ||
| 71 | - /// And the memory management will be similar. | ||
| 72 | - /// | ||
| 73 | - /// Subsequent calls to [Get.lazyPut()] with the same parameters | ||
| 74 | - /// (<[S]> and optionally [tag] will **not** override the original). | ||
| 75 | - void lazyPut<S>( | ||
| 76 | - InstanceBuilderCallback<S> builder, { | ||
| 77 | - String tag, | ||
| 78 | - bool fenix, | ||
| 79 | - }) { | ||
| 80 | - _insert( | ||
| 81 | - isSingleton: true, | ||
| 82 | - name: tag, | ||
| 83 | - permanent: fenix ?? Get.smartManagement == SmartManagement.keepFactory, | ||
| 84 | - builder: builder, | ||
| 85 | - ); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | void printInstanceStack() { | 53 | void printInstanceStack() { |
| 89 | Get.log(_routesKey.toString()); | 54 | Get.log(_routesKey.toString()); |
| 90 | } | 55 | } |
| @@ -138,6 +103,43 @@ class GetInstance { | @@ -138,6 +103,43 @@ class GetInstance { | ||
| 138 | return find<S>(tag: tag); | 103 | return find<S>(tag: tag); |
| 139 | } | 104 | } |
| 140 | 105 | ||
| 106 | + /// Creates a new Instance<S> lazily from the [<S>builder()] callback. | ||
| 107 | + /// | ||
| 108 | + /// The first time you call [Get.find()], the [builder()] callback will create | ||
| 109 | + /// the Instance and persisted as a Singleton (like you would | ||
| 110 | + /// use [Get.put()]). | ||
| 111 | + /// | ||
| 112 | + /// Using [Get.smartManagement] as [SmartManagement.keepFactory] has | ||
| 113 | + /// the same outcome as using [fenix:true] : | ||
| 114 | + /// The internal register of [builder()] will remain in memory to recreate | ||
| 115 | + /// the Instance if the Instance has been removed with [Get.delete()]. | ||
| 116 | + /// Therefore, future calls to [Get.find()] will return the same Instance. | ||
| 117 | + /// | ||
| 118 | + /// If you need to make use of GetxController's life-cycle | ||
| 119 | + /// ([onInit(), onStart(), onClose()]) [fenix] is a great choice to mix with | ||
| 120 | + /// [GetBuilder()] and [GetX()] widgets, and/or [GetMaterialApp] Navigation. | ||
| 121 | + /// | ||
| 122 | + /// You could use [Get.lazyPut(fenix:true)] in your app's [main()] instead | ||
| 123 | + /// of [Bindings()] for each [GetPage]. | ||
| 124 | + /// And the memory management will be similar. | ||
| 125 | + /// | ||
| 126 | + /// Subsequent calls to [Get.lazyPut()] with the same parameters | ||
| 127 | + /// (<[S]> and optionally [tag] will **not** override the original). | ||
| 128 | + void lazyPut<S>( | ||
| 129 | + InstanceBuilderCallback<S> builder, { | ||
| 130 | + String tag, | ||
| 131 | + bool fenix, | ||
| 132 | + bool permanent = false, | ||
| 133 | + }) { | ||
| 134 | + _insert( | ||
| 135 | + isSingleton: true, | ||
| 136 | + name: tag, | ||
| 137 | + permanent: permanent, | ||
| 138 | + builder: builder, | ||
| 139 | + fenix: fenix ?? Get.smartManagement == SmartManagement.keepFactory, | ||
| 140 | + ); | ||
| 141 | + } | ||
| 142 | + | ||
| 141 | /// Creates a new Class Instance [S] from the builder callback[S]. | 143 | /// Creates a new Class Instance [S] from the builder callback[S]. |
| 142 | /// Every time [find]<[S]>() is used, it calls the builder method to generate | 144 | /// Every time [find]<[S]>() is used, it calls the builder method to generate |
| 143 | /// a new Instance [S]. | 145 | /// a new Instance [S]. |
| @@ -173,6 +175,7 @@ class GetInstance { | @@ -173,6 +175,7 @@ class GetInstance { | ||
| 173 | String name, | 175 | String name, |
| 174 | bool permanent = false, | 176 | bool permanent = false, |
| 175 | InstanceBuilderCallback<S> builder, | 177 | InstanceBuilderCallback<S> builder, |
| 178 | + bool fenix = false, | ||
| 176 | }) { | 179 | }) { |
| 177 | assert(builder != null); | 180 | assert(builder != null); |
| 178 | final key = _getKey(S, name); | 181 | final key = _getKey(S, name); |
| @@ -183,6 +186,7 @@ class GetInstance { | @@ -183,6 +186,7 @@ class GetInstance { | ||
| 183 | builder, | 186 | builder, |
| 184 | permanent, | 187 | permanent, |
| 185 | false, | 188 | false, |
| 189 | + fenix, | ||
| 186 | ), | 190 | ), |
| 187 | ); | 191 | ); |
| 188 | } | 192 | } |
| @@ -374,6 +378,7 @@ class GetInstance { | @@ -374,6 +378,7 @@ class GetInstance { | ||
| 374 | } | 378 | } |
| 375 | 379 | ||
| 376 | final builder = _singl[newKey]; | 380 | final builder = _singl[newKey]; |
| 381 | + | ||
| 377 | if (builder.permanent && !force) { | 382 | if (builder.permanent && !force) { |
| 378 | Get.log( | 383 | Get.log( |
| 379 | // ignore: lines_longer_than_80_chars | 384 | // ignore: lines_longer_than_80_chars |
| @@ -393,12 +398,16 @@ class GetInstance { | @@ -393,12 +398,16 @@ class GetInstance { | ||
| 393 | Get.log('"$newKey" onDelete() called'); | 398 | Get.log('"$newKey" onDelete() called'); |
| 394 | } | 399 | } |
| 395 | 400 | ||
| 396 | - _singl.remove(newKey); | ||
| 397 | - | ||
| 398 | - if (_singl.containsKey(newKey)) { | ||
| 399 | - Get.log('Error removing object "$newKey"', isError: true); | 401 | + if (builder.fenix) { |
| 402 | + builder.dependency = null; | ||
| 403 | + builder.isInit = false; | ||
| 400 | } else { | 404 | } else { |
| 401 | - Get.log('"$newKey" deleted from memory'); | 405 | + _singl.remove(newKey); |
| 406 | + if (_singl.containsKey(newKey)) { | ||
| 407 | + Get.log('Error removing object "$newKey"', isError: true); | ||
| 408 | + } else { | ||
| 409 | + Get.log('"$newKey" deleted from memory'); | ||
| 410 | + } | ||
| 402 | } | 411 | } |
| 403 | 412 | ||
| 404 | return true; | 413 | return true; |
| @@ -469,6 +478,10 @@ class _InstanceBuilderFactory<S> { | @@ -469,6 +478,10 @@ class _InstanceBuilderFactory<S> { | ||
| 469 | /// For reusing [dependency] instead of [builderFunc] | 478 | /// For reusing [dependency] instead of [builderFunc] |
| 470 | bool isSingleton; | 479 | bool isSingleton; |
| 471 | 480 | ||
| 481 | + /// When fenix mode is avaliable, when a new instance is need | ||
| 482 | + /// Instance manager will recreate a new instance of S | ||
| 483 | + bool fenix; | ||
| 484 | + | ||
| 472 | /// Stores the actual object instance when [isSingleton]=true. | 485 | /// Stores the actual object instance when [isSingleton]=true. |
| 473 | S dependency; | 486 | S dependency; |
| 474 | 487 | ||
| @@ -487,6 +500,7 @@ class _InstanceBuilderFactory<S> { | @@ -487,6 +500,7 @@ class _InstanceBuilderFactory<S> { | ||
| 487 | this.builderFunc, | 500 | this.builderFunc, |
| 488 | this.permanent, | 501 | this.permanent, |
| 489 | this.isInit, | 502 | this.isInit, |
| 503 | + this.fenix, | ||
| 490 | ); | 504 | ); |
| 491 | 505 | ||
| 492 | /// Gets the actual instance by it's [builderFunc] or the persisted instance. | 506 | /// Gets the actual instance by it's [builderFunc] or the persisted instance. |
| @@ -486,7 +486,7 @@ extension GetNavigation on GetInterface { | @@ -486,7 +486,7 @@ extension GetNavigation on GetInterface { | ||
| 486 | /// By default, GetX will prevent you from push a route that you already in, | 486 | /// By default, GetX will prevent you from push a route that you already in, |
| 487 | /// if you want to push anyway, set [preventDuplicates] to false | 487 | /// if you want to push anyway, set [preventDuplicates] to false |
| 488 | Future<T> to<T>( | 488 | Future<T> to<T>( |
| 489 | - Widget page, { | 489 | + dynamic page, { |
| 490 | bool opaque, | 490 | bool opaque, |
| 491 | Transition transition, | 491 | Transition transition, |
| 492 | Curve curve, | 492 | Curve curve, |
| @@ -505,7 +505,7 @@ extension GetNavigation on GetInterface { | @@ -505,7 +505,7 @@ extension GetNavigation on GetInterface { | ||
| 505 | return global(id)?.currentState?.push<T>( | 505 | return global(id)?.currentState?.push<T>( |
| 506 | GetPageRoute<T>( | 506 | GetPageRoute<T>( |
| 507 | opaque: opaque ?? true, | 507 | opaque: opaque ?? true, |
| 508 | - page: () => page, | 508 | + page: _resolve(page, 'to'), |
| 509 | routeName: routeName, | 509 | routeName: routeName, |
| 510 | settings: RouteSettings( | 510 | settings: RouteSettings( |
| 511 | // name: forceRouteName ? '${a.runtimeType}' : '', | 511 | // name: forceRouteName ? '${a.runtimeType}' : '', |
| @@ -521,6 +521,21 @@ extension GetNavigation on GetInterface { | @@ -521,6 +521,21 @@ extension GetNavigation on GetInterface { | ||
| 521 | ); | 521 | ); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | + GetPageBuilder _resolve(dynamic page, String method) { | ||
| 525 | + if (page is GetPageBuilder) { | ||
| 526 | + return page; | ||
| 527 | + } else if (page is Widget) { | ||
| 528 | + Get.log( | ||
| 529 | + '''WARNING, consider using: "Get.$method(() => Page())" instead of "Get.to(Page())". | ||
| 530 | +Using a widget function instead of a widget fully guarantees that the widget and its controllers will be removed from memory when they are no longer used. | ||
| 531 | + '''); | ||
| 532 | + return () => page; | ||
| 533 | + } else { | ||
| 534 | + throw '''Unexpected format, | ||
| 535 | +you can only use widgets and widget functions here'''; | ||
| 536 | + } | ||
| 537 | + } | ||
| 538 | + | ||
| 524 | /// **Navigation.pushNamed()** shortcut.<br><br> | 539 | /// **Navigation.pushNamed()** shortcut.<br><br> |
| 525 | /// | 540 | /// |
| 526 | /// Pushes a new named [page] to the stack. | 541 | /// Pushes a new named [page] to the stack. |
| @@ -836,7 +851,7 @@ extension GetNavigation on GetInterface { | @@ -836,7 +851,7 @@ extension GetNavigation on GetInterface { | ||
| 836 | /// By default, GetX will prevent you from push a route that you already in, | 851 | /// By default, GetX will prevent you from push a route that you already in, |
| 837 | /// if you want to push anyway, set [preventDuplicates] to false | 852 | /// if you want to push anyway, set [preventDuplicates] to false |
| 838 | Future<T> off<T>( | 853 | Future<T> off<T>( |
| 839 | - Widget page, { | 854 | + dynamic page, { |
| 840 | bool opaque = false, | 855 | bool opaque = false, |
| 841 | Transition transition, | 856 | Transition transition, |
| 842 | Curve curve, | 857 | Curve curve, |
| @@ -854,7 +869,7 @@ extension GetNavigation on GetInterface { | @@ -854,7 +869,7 @@ extension GetNavigation on GetInterface { | ||
| 854 | } | 869 | } |
| 855 | return global(id)?.currentState?.pushReplacement(GetPageRoute( | 870 | return global(id)?.currentState?.pushReplacement(GetPageRoute( |
| 856 | opaque: opaque ?? true, | 871 | opaque: opaque ?? true, |
| 857 | - page: () => page, | 872 | + page: _resolve(page, 'off'), |
| 858 | binding: binding, | 873 | binding: binding, |
| 859 | settings: RouteSettings(arguments: arguments), | 874 | settings: RouteSettings(arguments: arguments), |
| 860 | routeName: routeName, | 875 | routeName: routeName, |
| @@ -897,7 +912,7 @@ extension GetNavigation on GetInterface { | @@ -897,7 +912,7 @@ extension GetNavigation on GetInterface { | ||
| 897 | /// By default, GetX will prevent you from push a route that you already in, | 912 | /// By default, GetX will prevent you from push a route that you already in, |
| 898 | /// if you want to push anyway, set [preventDuplicates] to false | 913 | /// if you want to push anyway, set [preventDuplicates] to false |
| 899 | Future<T> offAll<T>( | 914 | Future<T> offAll<T>( |
| 900 | - Widget page, { | 915 | + dynamic page, { |
| 901 | RoutePredicate predicate, | 916 | RoutePredicate predicate, |
| 902 | bool opaque = false, | 917 | bool opaque = false, |
| 903 | bool popGesture, | 918 | bool popGesture, |
| @@ -915,7 +930,7 @@ extension GetNavigation on GetInterface { | @@ -915,7 +930,7 @@ extension GetNavigation on GetInterface { | ||
| 915 | GetPageRoute<T>( | 930 | GetPageRoute<T>( |
| 916 | opaque: opaque ?? true, | 931 | opaque: opaque ?? true, |
| 917 | popGesture: popGesture ?? defaultPopGesture, | 932 | popGesture: popGesture ?? defaultPopGesture, |
| 918 | - page: () => page, | 933 | + page: _resolve(page, 'offAll'), |
| 919 | binding: binding, | 934 | binding: binding, |
| 920 | settings: RouteSettings(arguments: arguments), | 935 | settings: RouteSettings(arguments: arguments), |
| 921 | fullscreenDialog: fullscreenDialog, | 936 | fullscreenDialog: fullscreenDialog, |
| @@ -26,30 +26,30 @@ mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { | @@ -26,30 +26,30 @@ mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { | ||
| 26 | typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function( | 26 | typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function( |
| 27 | T controller); | 27 | T controller); |
| 28 | 28 | ||
| 29 | -class _InheritedGetxController<T extends GetxController> | ||
| 30 | - extends InheritedWidget { | ||
| 31 | - final T model; | ||
| 32 | - final int version; | ||
| 33 | - | ||
| 34 | - _InheritedGetxController({ | ||
| 35 | - Key key, | ||
| 36 | - @required Widget child, | ||
| 37 | - @required this.model, | ||
| 38 | - }) : version = model.notifierVersion, | ||
| 39 | - super(key: key, child: child); | ||
| 40 | - | ||
| 41 | - @override | ||
| 42 | - bool updateShouldNotify(_InheritedGetxController<T> oldWidget) => | ||
| 43 | - (oldWidget.version != version); | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -extension WatchEtx on GetxController { | ||
| 47 | - T watch<T extends GetxController>() { | ||
| 48 | - final instance = Get.find<T>(); | ||
| 49 | - _GetBuilderState._currentState.watch(instance.update); | ||
| 50 | - return instance; | ||
| 51 | - } | ||
| 52 | -} | 29 | +// class _InheritedGetxController<T extends GetxController> |
| 30 | +// extends InheritedWidget { | ||
| 31 | +// final T model; | ||
| 32 | +// final int version; | ||
| 33 | + | ||
| 34 | +// _InheritedGetxController({ | ||
| 35 | +// Key key, | ||
| 36 | +// @required Widget child, | ||
| 37 | +// @required this.model, | ||
| 38 | +// }) : version = model.notifierVersion, | ||
| 39 | +// super(key: key, child: child); | ||
| 40 | + | ||
| 41 | +// @override | ||
| 42 | +// bool updateShouldNotify(_InheritedGetxController<T> oldWidget) => | ||
| 43 | +// (oldWidget.version != version); | ||
| 44 | +// } | ||
| 45 | + | ||
| 46 | +// extension WatchEtx on GetxController { | ||
| 47 | +// T watch<T extends GetxController>() { | ||
| 48 | +// final instance = Get.find<T>(); | ||
| 49 | +// _GetBuilderState._currentState.watch(instance.update); | ||
| 50 | +// return instance; | ||
| 51 | +// } | ||
| 52 | +// } | ||
| 53 | 53 | ||
| 54 | class GetBuilder<T extends GetxController> extends StatefulWidget { | 54 | class GetBuilder<T extends GetxController> extends StatefulWidget { |
| 55 | final GetControllerBuilder<T> builder; | 55 | final GetControllerBuilder<T> builder; |
| @@ -58,7 +58,7 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | @@ -58,7 +58,7 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | ||
| 58 | final String tag; | 58 | final String tag; |
| 59 | final bool autoRemove; | 59 | final bool autoRemove; |
| 60 | final bool assignId; | 60 | final bool assignId; |
| 61 | - final Object Function(T value) selector; | 61 | + final Object Function(T value) filter; |
| 62 | final void Function(State state) initState, dispose, didChangeDependencies; | 62 | final void Function(State state) initState, dispose, didChangeDependencies; |
| 63 | final void Function(GetBuilder oldWidget, State state) didUpdateWidget; | 63 | final void Function(GetBuilder oldWidget, State state) didUpdateWidget; |
| 64 | final T init; | 64 | final T init; |
| @@ -71,7 +71,7 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | @@ -71,7 +71,7 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | ||
| 71 | this.autoRemove = true, | 71 | this.autoRemove = true, |
| 72 | this.assignId = false, | 72 | this.assignId = false, |
| 73 | this.initState, | 73 | this.initState, |
| 74 | - this.selector, | 74 | + this.filter, |
| 75 | this.tag, | 75 | this.tag, |
| 76 | this.dispose, | 76 | this.dispose, |
| 77 | this.id, | 77 | this.id, |
| @@ -80,24 +80,24 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | @@ -80,24 +80,24 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { | ||
| 80 | }) : assert(builder != null), | 80 | }) : assert(builder != null), |
| 81 | super(key: key); | 81 | super(key: key); |
| 82 | 82 | ||
| 83 | - static T of<T extends GetxController>( | ||
| 84 | - BuildContext context, { | ||
| 85 | - bool rebuild = false, | ||
| 86 | - }) { | ||
| 87 | - var widget = rebuild | ||
| 88 | - ? context | ||
| 89 | - .dependOnInheritedWidgetOfExactType<_InheritedGetxController<T>>() | ||
| 90 | - : context | ||
| 91 | - .getElementForInheritedWidgetOfExactType< | ||
| 92 | - _InheritedGetxController<T>>() | ||
| 93 | - ?.widget; | ||
| 94 | - | ||
| 95 | - if (widget == null) { | ||
| 96 | - throw 'Error: Could not find the correct dependency.'; | ||
| 97 | - } else { | ||
| 98 | - return (widget as _InheritedGetxController<T>).model; | ||
| 99 | - } | ||
| 100 | - } | 83 | + // static T of<T extends GetxController>( |
| 84 | + // BuildContext context, { | ||
| 85 | + // bool rebuild = false, | ||
| 86 | + // }) { | ||
| 87 | + // var widget = rebuild | ||
| 88 | + // ? context | ||
| 89 | + // .dependOnInheritedWidgetOfExactType<_InheritedGetxController<T>>() | ||
| 90 | + // : context | ||
| 91 | + // .getElementForInheritedWidgetOfExactType< | ||
| 92 | + // _InheritedGetxController<T>>() | ||
| 93 | + // ?.widget; | ||
| 94 | + | ||
| 95 | + // if (widget == null) { | ||
| 96 | + // throw 'Error: Could not find the correct dependency.'; | ||
| 97 | + // } else { | ||
| 98 | + // return (widget as _InheritedGetxController<T>).model; | ||
| 99 | + // } | ||
| 100 | + // } | ||
| 101 | 101 | ||
| 102 | @override | 102 | @override |
| 103 | _GetBuilderState<T> createState() => _GetBuilderState<T>(); | 103 | _GetBuilderState<T> createState() => _GetBuilderState<T>(); |
| @@ -108,10 +108,10 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -108,10 +108,10 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 108 | T controller; | 108 | T controller; |
| 109 | bool isCreator = false; | 109 | bool isCreator = false; |
| 110 | VoidCallback remove; | 110 | VoidCallback remove; |
| 111 | - Object _selector; | 111 | + Object _filter; |
| 112 | List<VoidCallback> _watchs; | 112 | List<VoidCallback> _watchs; |
| 113 | 113 | ||
| 114 | - static _GetBuilderState _currentState; | 114 | + // static _GetBuilderState _currentState; |
| 115 | 115 | ||
| 116 | void watch(VoidCallback listener) { | 116 | void watch(VoidCallback listener) { |
| 117 | (_watchs ??= <VoidCallback>[]).add(listener); | 117 | (_watchs ??= <VoidCallback>[]).add(listener); |
| @@ -119,7 +119,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -119,7 +119,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 119 | 119 | ||
| 120 | @override | 120 | @override |
| 121 | void initState() { | 121 | void initState() { |
| 122 | - _GetBuilderState._currentState = this; | 122 | + // _GetBuilderState._currentState = this; |
| 123 | super.initState(); | 123 | super.initState(); |
| 124 | widget.initState?.call(this); | 124 | widget.initState?.call(this); |
| 125 | 125 | ||
| @@ -144,8 +144,8 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -144,8 +144,8 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 144 | controller?.onStart(); | 144 | controller?.onStart(); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | - if (widget.selector != null) { | ||
| 148 | - _selector = widget.selector(controller); | 147 | + if (widget.filter != null) { |
| 148 | + _filter = widget.filter(controller); | ||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | _subscribeToController(); | 151 | _subscribeToController(); |
| @@ -158,18 +158,18 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -158,18 +158,18 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 158 | remove?.call(); | 158 | remove?.call(); |
| 159 | remove = (widget.id == null) | 159 | remove = (widget.id == null) |
| 160 | ? controller?.addListener( | 160 | ? controller?.addListener( |
| 161 | - _selector != null ? _selectorUpdate : getUpdate, | 161 | + _filter != null ? _filterUpdate : getUpdate, |
| 162 | ) | 162 | ) |
| 163 | : controller?.addListenerId( | 163 | : controller?.addListenerId( |
| 164 | widget.id, | 164 | widget.id, |
| 165 | - _selector != null ? _selectorUpdate : getUpdate, | 165 | + _filter != null ? _filterUpdate : getUpdate, |
| 166 | ); | 166 | ); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | - void _selectorUpdate() { | ||
| 170 | - var newSelector = widget.selector(controller); | ||
| 171 | - if (newSelector != _selector) { | ||
| 172 | - _selector = newSelector; | 169 | + void _filterUpdate() { |
| 170 | + var newFilter = widget.filter(controller); | ||
| 171 | + if (newFilter != _filter) { | ||
| 172 | + _filter = newFilter; | ||
| 173 | getUpdate(); | 173 | getUpdate(); |
| 174 | } | 174 | } |
| 175 | } | 175 | } |
| @@ -189,7 +189,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -189,7 +189,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 189 | controller = null; | 189 | controller = null; |
| 190 | isCreator = null; | 190 | isCreator = null; |
| 191 | remove = null; | 191 | remove = null; |
| 192 | - _selector = null; | 192 | + _filter = null; |
| 193 | _watchs = null; | 193 | _watchs = null; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| @@ -211,21 +211,22 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -211,21 +211,22 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
| 211 | 211 | ||
| 212 | @override | 212 | @override |
| 213 | Widget build(BuildContext context) { | 213 | Widget build(BuildContext context) { |
| 214 | - return _InheritedGetxController<T>( | ||
| 215 | - model: controller, | ||
| 216 | - child: widget.builder(controller), | ||
| 217 | - ); | ||
| 218 | - } | ||
| 219 | -} | ||
| 220 | - | ||
| 221 | -extension FindExt on BuildContext { | ||
| 222 | - T find<T extends GetxController>() { | ||
| 223 | - return GetBuilder.of<T>(this, rebuild: false); | 214 | + // return _InheritedGetxController<T>( |
| 215 | + // model: controller, | ||
| 216 | + // child: widget.builder(controller), | ||
| 217 | + // ); | ||
| 218 | + return widget.builder(controller); | ||
| 224 | } | 219 | } |
| 225 | } | 220 | } |
| 226 | 221 | ||
| 227 | -extension ObserverEtx on BuildContext { | ||
| 228 | - T obs<T extends GetxController>() { | ||
| 229 | - return GetBuilder.of<T>(this, rebuild: true); | ||
| 230 | - } | ||
| 231 | -} | 222 | +// extension FindExt on BuildContext { |
| 223 | +// T find<T extends GetxController>() { | ||
| 224 | +// return GetBuilder.of<T>(this, rebuild: false); | ||
| 225 | +// } | ||
| 226 | +// } | ||
| 227 | + | ||
| 228 | +// extension ObserverEtx on BuildContext { | ||
| 229 | +// T obs<T extends GetxController>() { | ||
| 230 | +// return GetBuilder.of<T>(this, rebuild: true); | ||
| 231 | +// } | ||
| 232 | +// } |
| @@ -79,4 +79,9 @@ extension GetStringUtils on String { | @@ -79,4 +79,9 @@ extension GetStringUtils on String { | ||
| 79 | 79 | ||
| 80 | String numericOnly({bool firstWordOnly = false}) => | 80 | String numericOnly({bool firstWordOnly = false}) => |
| 81 | GetUtils.numericOnly(this, firstWordOnly: firstWordOnly); | 81 | GetUtils.numericOnly(this, firstWordOnly: firstWordOnly); |
| 82 | + | ||
| 83 | + String createPath([Iterable segments]) { | ||
| 84 | + final path = startsWith('/') ? this : '/$this'; | ||
| 85 | + return GetUtils.createPath(path, segments); | ||
| 86 | + } | ||
| 82 | } | 87 | } |
| @@ -578,6 +578,14 @@ class GetUtils { | @@ -578,6 +578,14 @@ class GetUtils { | ||
| 578 | return (value == null) ? false : RegExp(pattern).hasMatch(value); | 578 | return (value == null) ? false : RegExp(pattern).hasMatch(value); |
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | + static String createPath(String path, [Iterable segments]) { | ||
| 582 | + if (segments == null || segments.isEmpty) { | ||
| 583 | + return path; | ||
| 584 | + } | ||
| 585 | + final list = segments.map((e) => '/$e'); | ||
| 586 | + return path + list.join(); | ||
| 587 | + } | ||
| 588 | + | ||
| 581 | static void printFunction( | 589 | static void printFunction( |
| 582 | String prefix, | 590 | String prefix, |
| 583 | dynamic value, | 591 | dynamic value, |
| @@ -81,6 +81,26 @@ void main() { | @@ -81,6 +81,26 @@ void main() { | ||
| 81 | Get.reset(); | 81 | Get.reset(); |
| 82 | }); | 82 | }); |
| 83 | 83 | ||
| 84 | + test('Get.lazyPut fenix test', () async { | ||
| 85 | + Get.lazyPut<Controller>(() => Controller(), fenix: true); | ||
| 86 | + Get.find<Controller>().increment(); | ||
| 87 | + | ||
| 88 | + expect(Get.find<Controller>().count, 1); | ||
| 89 | + Get.delete<Controller>(); | ||
| 90 | + expect(Get.find<Controller>().count, 0); | ||
| 91 | + Get.reset(); | ||
| 92 | + }); | ||
| 93 | + | ||
| 94 | + test('Get.lazyPut without fenix', () async { | ||
| 95 | + Get.lazyPut<Controller>(() => Controller()); | ||
| 96 | + Get.find<Controller>().increment(); | ||
| 97 | + | ||
| 98 | + expect(Get.find<Controller>().count, 1); | ||
| 99 | + Get.delete<Controller>(); | ||
| 100 | + expect(() => Get.find<Controller>(), throwsA(m.TypeMatcher<String>())); | ||
| 101 | + Get.reset(); | ||
| 102 | + }); | ||
| 103 | + | ||
| 84 | test('Get.reloadInstance test', () async { | 104 | test('Get.reloadInstance test', () async { |
| 85 | Get.lazyPut<Controller>(() => Controller()); | 105 | Get.lazyPut<Controller>(() => Controller()); |
| 86 | var ct1 = Get.find<Controller>(); | 106 | var ct1 = Get.find<Controller>(); |
-
Please register or login to post a comment