Jonny Borges

refactor Binds, remove disposable interface, create a more composable api

Showing 34 changed files with 670 additions and 433 deletions
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
3 3
4 -import 'lang/translation_service.dart';  
5 -import 'routes/app_pages.dart';  
6 -import 'shared/logger/logger_utils.dart';  
7 -  
8 void main() { 4 void main() {
9 - runApp(MyApp()); 5 + //MyBindings().dependencies();
  6 + runApp(
  7 + Binds(
  8 + binds: [
  9 + Bind.lazyPut(() => Controller()),
  10 + Bind.lazyPut(() => Controller2()),
  11 + ],
  12 + child: GetMaterialApp(
  13 + home: Home(),
  14 + ),
  15 + ),
  16 + );
10 } 17 }
11 18
12 -class MyApp extends StatelessWidget {  
13 - const MyApp({Key? key}) : super(key: key);  
14 19
  20 +
  21 +class MyBindings extends Binding {
15 @override 22 @override
16 - Widget build(BuildContext context) {  
17 - return GetMaterialApp.router(  
18 - debugShowCheckedModeBanner: false,  
19 - enableLog: true,  
20 - logWriterCallback: Logger.write,  
21 - // initialRoute: AppPages.INITIAL,  
22 - getPages: AppPages.routes,  
23 - locale: TranslationService.locale,  
24 - fallbackLocale: TranslationService.fallbackLocale,  
25 - translations: TranslationService(),  
26 - ); 23 + List<Bind> dependencies() {
  24 + return [
  25 + Bind.put(Controller()),
  26 + Bind.put(Controller2()),
  27 + ];
27 } 28 }
28 } 29 }
29 30
30 -/// Nav 2 snippet  
31 -// void main() {  
32 -// runApp(MyApp());  
33 -// }  
34 -  
35 -// class MyApp extends StatelessWidget {  
36 -// MyApp({Key? key}) : super(key: key); 31 +class Controller extends GetxController {
  32 + final count = 0.obs;
  33 + void increment() {
  34 + count.value++;
  35 + update();
  36 + }
  37 +}
37 38
38 -// @override  
39 -// Widget build(BuildContext context) {  
40 -// return GetMaterialApp.router(  
41 -// getPages: [  
42 -// GetPage(  
43 -// participatesInRootNavigator: true,  
44 -// name: '/first',  
45 -// page: () => First()),  
46 -// GetPage(  
47 -// name: '/second',  
48 -// page: () => Second(),  
49 -// ),  
50 -// GetPage(  
51 -// name: '/third',  
52 -// page: () => Third(),  
53 -// ),  
54 -// ],  
55 -// debugShowCheckedModeBanner: false,  
56 -// );  
57 -// }  
58 -// } 39 +class Controller2 extends GetxController {
  40 + final count = 0.obs;
59 41
60 -// class First extends StatelessWidget {  
61 -// @override  
62 -// Widget build(BuildContext context) {  
63 -// return Scaffold(  
64 -// appBar: AppBar(  
65 -// title: Text('page one'),  
66 -// leading: IconButton(  
67 -// icon: Icon(Icons.more),  
68 -// onPressed: () {  
69 -// Get.changeTheme(  
70 -// context.isDarkMode ? ThemeData.light() : ThemeData.dark());  
71 -// },  
72 -// ),  
73 -// ),  
74 -// body: Center(  
75 -// child: Container(  
76 -// height: 300,  
77 -// width: 300,  
78 -// child: ElevatedButton(  
79 -// onPressed: () {},  
80 -// child: Text('next screen'),  
81 -// ),  
82 -// ),  
83 -// ),  
84 -// );  
85 -// }  
86 -// } 42 + Controller2();
  43 + void increment() {
  44 + count.value++;
  45 + update();
  46 + }
  47 +}
87 48
88 -// class Second extends StatelessWidget {  
89 -// @override  
90 -// Widget build(BuildContext context) {  
91 -// return Scaffold(  
92 -// appBar: AppBar(  
93 -// title: Text('page two ${Get.parameters["id"]}'),  
94 -// ),  
95 -// body: Center(  
96 -// child: Container(  
97 -// height: 300,  
98 -// width: 300,  
99 -// child: ElevatedButton(  
100 -// onPressed: () {},  
101 -// child: Text('next screen'),  
102 -// ),  
103 -// ),  
104 -// ),  
105 -// );  
106 -// }  
107 -// } 49 +class Home extends ObxStatelessWidget {
  50 + const Home({Key? key}) : super(key: key);
  51 + @override
  52 + Widget build(BuildContext context) {
  53 + print('sasasasa');
  54 + return Scaffold(
  55 + appBar: AppBar(title: Text("counter")),
  56 + body: Builder(builder: (context) {
  57 + return Center(
  58 + child: Column(
  59 + mainAxisAlignment: MainAxisAlignment.center,
  60 + children: [
  61 + Builder(builder: (context) {
  62 + print('builder');
  63 + final controller = context.listen<Controller>();
  64 + return Text('${controller.count.value}');
  65 + }),
  66 + ElevatedButton(
  67 + child: Text('Next Route'),
  68 + onPressed: () {
  69 + Get.to(() => Second());
  70 + },
  71 + ),
  72 + ],
  73 + ),
  74 + );
  75 + }),
  76 + floatingActionButton: FloatingActionButton(
  77 + child: Icon(Icons.add),
  78 + onPressed: () {
  79 + Get.find<Controller>().increment();
  80 + },
  81 + ),
  82 + );
  83 + }
  84 +}
108 85
109 -// class Third extends StatelessWidget {  
110 -// @override  
111 -// Widget build(BuildContext context) {  
112 -// return Scaffold(  
113 -// backgroundColor: Colors.red,  
114 -// appBar: AppBar(  
115 -// title: Text('page three'),  
116 -// ),  
117 -// body: Center(  
118 -// child: Container(  
119 -// height: 300,  
120 -// width: 300,  
121 -// child: ElevatedButton(  
122 -// onPressed: () {},  
123 -// child: Text('go to first screen'),  
124 -// ),  
125 -// ),  
126 -// ),  
127 -// );  
128 -// }  
129 -// } 86 +class Second extends StatelessWidget {
  87 + @override
  88 + Widget build(BuildContext context) {
  89 + return Scaffold(
  90 + appBar: AppBar(),
  91 + floatingActionButton: FloatingActionButton(
  92 + onPressed: () {
  93 + context.get<Controller2>().increment();
  94 + },
  95 + ),
  96 + body: Center(
  97 + child: Builder(builder: (context) {
  98 + final ctrl = context.listen<Controller2>();
  99 + return Text("${ctrl.count}");
  100 + }),
  101 + ),
  102 + );
  103 + }
  104 +}
1 import 'package:get/get.dart'; 1 import 'package:get/get.dart';
2 -import '../data/home_api_provider.dart';  
3 2
  3 +import '../data/home_api_provider.dart';
4 import '../data/home_repository.dart'; 4 import '../data/home_repository.dart';
5 import '../domain/adapters/repository_adapter.dart'; 5 import '../domain/adapters/repository_adapter.dart';
6 import '../presentation/controllers/home_controller.dart'; 6 import '../presentation/controllers/home_controller.dart';
7 7
8 -class HomeBinding extends Bindings { 8 +class HomeBinding extends Binding {
9 @override 9 @override
10 - void dependencies() {  
11 - Get.lazyPut<IHomeProvider>(() => HomeProvider());  
12 - Get.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find()));  
13 - Get.lazyPut(() => HomeController(homeRepository: Get.find())); 10 + List<Bind> dependencies() {
  11 + return [
  12 + Bind.lazyPut<IHomeProvider>(() => HomeProvider()),
  13 + Bind.lazyPut<IHomeRepository>(() => HomeRepository(provider: Get.find())),
  14 + Bind.lazyPut(() => HomeController(homeRepository: Get.find())),
  15 + ];
14 } 16 }
15 } 17 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/dashboard_controller.dart'; 3 import '../controllers/dashboard_controller.dart';
4 4
5 -class DashboardBinding extends Bindings { 5 +class DashboardBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<DashboardController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<DashboardController>(
9 () => DashboardController(), 10 () => DashboardController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/home_controller.dart'; 3 import '../controllers/home_controller.dart';
4 4
5 -class HomeBinding extends Bindings { 5 +class HomeBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<HomeController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<HomeController>(
9 () => HomeController(), 10 () => HomeController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -2,11 +2,11 @@ import 'package:get/get.dart'; @@ -2,11 +2,11 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/login_controller.dart'; 3 import '../controllers/login_controller.dart';
4 4
5 -class LoginBinding extends Bindings { 5 +class LoginBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<LoginController>(  
9 - () => LoginController(),  
10 - ); 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut(() => LoginController()),
  10 + ];
11 } 11 }
12 } 12 }
@@ -2,13 +2,15 @@ import 'package:get/get.dart'; @@ -2,13 +2,15 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/product_details_controller.dart'; 3 import '../controllers/product_details_controller.dart';
4 4
5 -class ProductDetailsBinding extends Bindings { 5 +class ProductDetailsBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.create<ProductDetailsController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.create<ProductDetailsController>(
9 () => ProductDetailsController( 10 () => ProductDetailsController(
10 Get.parameters['productId'] ?? '', 11 Get.parameters['productId'] ?? '',
11 ), 12 ),
12 - ); 13 + )
  14 + ];
13 } 15 }
14 } 16 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/products_controller.dart'; 3 import '../controllers/products_controller.dart';
4 4
5 -class ProductsBinding extends Bindings { 5 +class ProductsBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<ProductsController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<ProductsController>(
9 () => ProductsController(), 10 () => ProductsController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/profile_controller.dart'; 3 import '../controllers/profile_controller.dart';
4 4
5 -class ProfileBinding extends Bindings { 5 +class ProfileBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<ProfileController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<ProfileController>(
9 () => ProfileController(), 10 () => ProfileController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/root_controller.dart'; 3 import '../controllers/root_controller.dart';
4 4
5 -class RootBinding extends Bindings { 5 +class RootBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<RootController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<RootController>(
9 () => RootController(), 10 () => RootController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -2,11 +2,13 @@ import 'package:get/get.dart'; @@ -2,11 +2,13 @@ import 'package:get/get.dart';
2 2
3 import '../controllers/settings_controller.dart'; 3 import '../controllers/settings_controller.dart';
4 4
5 -class SettingsBinding extends Bindings { 5 +class SettingsBinding extends Binding {
6 @override 6 @override
7 - void dependencies() {  
8 - Get.lazyPut<SettingsController>( 7 + List<Bind> dependencies() {
  8 + return [
  9 + Bind.lazyPut<SettingsController>(
9 () => SettingsController(), 10 () => SettingsController(),
10 - ); 11 + )
  12 + ];
11 } 13 }
12 } 14 }
@@ -46,9 +46,7 @@ class AppPages { @@ -46,9 +46,7 @@ class AppPages {
46 preventDuplicates: true, 46 preventDuplicates: true,
47 name: _Paths.HOME, 47 name: _Paths.HOME,
48 page: () => HomeView(), 48 page: () => HomeView(),
49 - bindings: [  
50 - HomeBinding(),  
51 - ], 49 + binding: HomeBinding(),
52 title: null, 50 title: null,
53 children: [ 51 children: [
54 GetPage( 52 GetPage(
@@ -12,7 +12,7 @@ export 'http/src/multipart/multipart_file.dart'; @@ -12,7 +12,7 @@ export 'http/src/multipart/multipart_file.dart';
12 export 'http/src/response/response.dart'; 12 export 'http/src/response/response.dart';
13 export 'sockets/sockets.dart'; 13 export 'sockets/sockets.dart';
14 14
15 -abstract class GetConnectInterface with GetLifeCycleBase { 15 +abstract class GetConnectInterface with GetLifeCycleMixin {
16 List<GetSocket>? sockets; 16 List<GetSocket>? sockets;
17 GetHttpClient get httpClient; 17 GetHttpClient get httpClient;
18 18
@@ -6,8 +6,9 @@ import 'get_instance.dart'; @@ -6,8 +6,9 @@ import 'get_instance.dart';
6 /// instance of Bindings to manage the 6 /// instance of Bindings to manage the
7 /// dependencies() (via Get.put()) for the Route you are opening. 7 /// dependencies() (via Get.put()) for the Route you are opening.
8 // ignore: one_member_abstracts 8 // ignore: one_member_abstracts
9 -abstract class Bindings {  
10 - void dependencies(); 9 +@Deprecated('Use Binding instead')
  10 +abstract class Bindings<T> {
  11 + T dependencies();
11 } 12 }
12 13
13 /// Simplifies Bindings generation from a single callback. 14 /// Simplifies Bindings generation from a single callback.
@@ -250,7 +250,7 @@ class GetInstance { @@ -250,7 +250,7 @@ class GetInstance {
250 S _startController<S>({String? tag}) { 250 S _startController<S>({String? tag}) {
251 final key = _getKey(S, tag); 251 final key = _getKey(S, tag);
252 final i = _singl[key]!.getDependency() as S; 252 final i = _singl[key]!.getDependency() as S;
253 - if (i is GetLifeCycleBase) { 253 + if (i is GetLifeCycleMixin) {
254 i.onStart(); 254 i.onStart();
255 if (tag == null) { 255 if (tag == null) {
256 Get.log('Instance "$S" has been initialized'); 256 Get.log('Instance "$S" has been initialized');
@@ -379,7 +379,7 @@ class GetInstance { @@ -379,7 +379,7 @@ class GetInstance {
379 return false; 379 return false;
380 } 380 }
381 381
382 - if (i is GetLifeCycleBase) { 382 + if (i is GetLifeCycleMixin) {
383 i.onDelete(); 383 i.onDelete();
384 Get.log('"$newKey" onDelete() called'); 384 Get.log('"$newKey" onDelete() called');
385 } 385 }
@@ -452,7 +452,7 @@ class GetInstance { @@ -452,7 +452,7 @@ class GetInstance {
452 return; 452 return;
453 } 453 }
454 454
455 - if (i is GetLifeCycleBase) { 455 + if (i is GetLifeCycleMixin) {
456 i.onDelete(); 456 i.onDelete();
457 Get.log('"$newKey" onDelete() called'); 457 Get.log('"$newKey" onDelete() called');
458 } 458 }
@@ -10,12 +10,14 @@ import 'package:flutter/scheduler.dart'; @@ -10,12 +10,14 @@ import 'package:flutter/scheduler.dart';
10 /// } 10 /// }
11 /// } 11 /// }
12 /// ``` 12 /// ```
13 -mixin GetLifeCycleBase { 13 +mixin GetLifeCycleMixin {
14 /// Called immediately after the widget is allocated in memory. 14 /// Called immediately after the widget is allocated in memory.
15 /// You might use this to initialize something for the controller. 15 /// You might use this to initialize something for the controller.
16 @protected 16 @protected
17 @mustCallSuper 17 @mustCallSuper
18 - void onInit() {} 18 + void onInit() {
  19 + SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
  20 + }
19 21
20 /// Called 1 frame after onInit(). It is the perfect place to enter 22 /// Called 1 frame after onInit(). It is the perfect place to enter
21 /// navigation events, like snackbar, dialogs, or a new route, or 23 /// navigation events, like snackbar, dialogs, or a new route, or
@@ -41,6 +43,7 @@ mixin GetLifeCycleBase { @@ -41,6 +43,7 @@ mixin GetLifeCycleBase {
41 /// lifetime cycle of the subclass. 43 /// lifetime cycle of the subclass.
42 // @protected 44 // @protected
43 @mustCallSuper 45 @mustCallSuper
  46 + @nonVirtual
44 void onStart() { 47 void onStart() {
45 // _checkIfAlreadyConfigured(); 48 // _checkIfAlreadyConfigured();
46 if (_initialized) return; 49 if (_initialized) return;
@@ -55,6 +58,7 @@ mixin GetLifeCycleBase { @@ -55,6 +58,7 @@ mixin GetLifeCycleBase {
55 58
56 // Called when the controller is removed from memory. 59 // Called when the controller is removed from memory.
57 @mustCallSuper 60 @mustCallSuper
  61 + @nonVirtual
58 void onDelete() { 62 void onDelete() {
59 if (_isClosed) return; 63 if (_isClosed) return;
60 _isClosed = true; 64 _isClosed = true;
@@ -70,13 +74,5 @@ mixin GetLifeCycleBase { @@ -70,13 +74,5 @@ mixin GetLifeCycleBase {
70 // } 74 // }
71 } 75 }
72 76
73 -abstract class GetLifeCycle with GetLifeCycleBase {  
74 - @override  
75 - void onInit() {  
76 - SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());  
77 - super.onInit();  
78 - }  
79 -}  
80 -  
81 /// Allow track difference between GetxServices and GetxControllers 77 /// Allow track difference between GetxServices and GetxControllers
82 mixin GetxServiceMixin {} 78 mixin GetxServiceMixin {}
@@ -2,6 +2,7 @@ import 'dart:ui' as ui; @@ -2,6 +2,7 @@ import 'dart:ui' as ui;
2 2
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:flutter/scheduler.dart'; 4 import 'package:flutter/scheduler.dart';
  5 +import 'package:get/get_state_manager/src/simple/get_state.dart';
5 6
6 import '../../get_core/get_core.dart'; 7 import '../../get_core/get_core.dart';
7 import '../../get_instance/src/bindings_interface.dart'; 8 import '../../get_instance/src/bindings_interface.dart';
@@ -508,7 +509,7 @@ extension GetNavigation on GetInterface { @@ -508,7 +509,7 @@ extension GetNavigation on GetInterface {
508 String? routeName, 509 String? routeName,
509 bool fullscreenDialog = false, 510 bool fullscreenDialog = false,
510 dynamic arguments, 511 dynamic arguments,
511 - Bindings? binding, 512 + Binding? binding,
512 bool preventDuplicates = true, 513 bool preventDuplicates = true,
513 bool? popGesture, 514 bool? popGesture,
514 bool showCupertinoParallax = true, 515 bool showCupertinoParallax = true,
@@ -894,7 +895,7 @@ you can only use widgets and widget functions here'''; @@ -894,7 +895,7 @@ you can only use widgets and widget functions here''';
894 int? id, 895 int? id,
895 String? routeName, 896 String? routeName,
896 dynamic arguments, 897 dynamic arguments,
897 - Bindings? binding, 898 + Binding? binding,
898 bool fullscreenDialog = false, 899 bool fullscreenDialog = false,
899 bool preventDuplicates = true, 900 bool preventDuplicates = true,
900 Duration? duration, 901 Duration? duration,
@@ -960,7 +961,7 @@ you can only use widgets and widget functions here'''; @@ -960,7 +961,7 @@ you can only use widgets and widget functions here''';
960 int? id, 961 int? id,
961 String? routeName, 962 String? routeName,
962 dynamic arguments, 963 dynamic arguments,
963 - Bindings? binding, 964 + Binding? binding,
964 bool fullscreenDialog = false, 965 bool fullscreenDialog = false,
965 Transition? transition, 966 Transition? transition,
966 Curve? curve, 967 Curve? curve,
@@ -6,8 +6,7 @@ import 'package:flutter/material.dart'; @@ -6,8 +6,7 @@ import 'package:flutter/material.dart';
6 import '../../../get.dart'; 6 import '../../../get.dart';
7 import '../../../get_state_manager/src/simple/list_notifier.dart'; 7 import '../../../get_state_manager/src/simple/list_notifier.dart';
8 8
9 -class GetDelegate extends RouterDelegate<GetNavConfig>  
10 - with ListenableMixin, ListNotifierMixin { 9 +class GetDelegate extends RouterDelegate<GetNavConfig> with ListNotifierMixin {
11 final List<GetNavConfig> history = <GetNavConfig>[]; 10 final List<GetNavConfig> history = <GetNavConfig>[];
12 final PopMode backButtonPopMode; 11 final PopMode backButtonPopMode;
13 final PreventDuplicateHandlingMode preventDuplicateHandlingMode; 12 final PreventDuplicateHandlingMode preventDuplicateHandlingMode;
@@ -44,7 +44,7 @@ class RouterReportManager<T> { @@ -44,7 +44,7 @@ class RouterReportManager<T> {
44 _routesByCreate.clear(); 44 _routesByCreate.clear();
45 } 45 }
46 46
47 - void appendRouteByCreate(GetLifeCycleBase i) { 47 + void appendRouteByCreate(GetLifeCycleMixin i) {
48 _routesByCreate[_current] ??= HashSet<Function>(); 48 _routesByCreate[_current] ??= HashSet<Function>();
49 // _routesByCreate[Get.reference]!.add(i.onDelete as Function); 49 // _routesByCreate[Get.reference]!.add(i.onDelete as Function);
50 _routesByCreate[_current]!.add(i.onDelete); 50 _routesByCreate[_current]!.add(i.onDelete);
@@ -40,7 +40,7 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T> @@ -40,7 +40,7 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
40 this.barrierDismissible = false, 40 this.barrierDismissible = false,
41 this.barrierColor, 41 this.barrierColor,
42 this.binding, 42 this.binding,
43 - this.bindings, 43 + this.binds,
44 this.routeName, 44 this.routeName,
45 this.page, 45 this.page,
46 this.title, 46 this.title,
@@ -61,9 +61,9 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T> @@ -61,9 +61,9 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
61 final String? routeName; 61 final String? routeName;
62 //final String reference; 62 //final String reference;
63 final CustomTransition? customTransition; 63 final CustomTransition? customTransition;
64 - final Bindings? binding; 64 + final Binding? binding;
65 final Map<String, String>? parameter; 65 final Map<String, String>? parameter;
66 - final List<Bindings>? bindings; 66 + final List<Bind>? binds;
67 67
68 @override 68 @override
69 final bool showCupertinoParallax; 69 final bool showCupertinoParallax;
@@ -102,18 +102,21 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T> @@ -102,18 +102,21 @@ class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
102 final middlewareRunner = MiddlewareRunner(middlewares); 102 final middlewareRunner = MiddlewareRunner(middlewares);
103 103
104 final localbindings = [ 104 final localbindings = [
105 - if (bindings != null) ...bindings!,  
106 - if (binding != null) ...[binding!] 105 + if (binds != null) ...binds!,
  106 + if (binding != null) ...binding!.dependencies(),
107 ]; 107 ];
108 final bindingsToBind = middlewareRunner.runOnBindingsStart(localbindings); 108 final bindingsToBind = middlewareRunner.runOnBindingsStart(localbindings);
109 - if (bindingsToBind != null) {  
110 - for (final binding in bindingsToBind) {  
111 - binding.dependencies();  
112 - }  
113 - }  
114 109
115 final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!; 110 final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;
  111 + if (bindingsToBind != null && bindingsToBind.isNotEmpty) {
  112 + _child = Binds(
  113 + child: middlewareRunner.runOnPageBuilt(pageToBuild()),
  114 + binds: bindingsToBind,
  115 + );
  116 + } else {
116 _child = middlewareRunner.runOnPageBuilt(pageToBuild()); 117 _child = middlewareRunner.runOnPageBuilt(pageToBuild());
  118 + }
  119 +
117 return _child!; 120 return _child!;
118 } 121 }
119 122
@@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart'; @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 3
4 import '../../../get_core/src/get_main.dart'; 4 import '../../../get_core/src/get_main.dart';
5 -import '../../../get_instance/get_instance.dart'; 5 +import '../../../get_state_manager/src/simple/get_state.dart';
6 import '../../get_navigation.dart'; 6 import '../../get_navigation.dart';
7 7
8 class GetPage<T> extends Page<T> { 8 class GetPage<T> extends Page<T> {
@@ -17,8 +17,8 @@ class GetPage<T> extends Page<T> { @@ -17,8 +17,8 @@ class GetPage<T> extends Page<T> {
17 final bool maintainState; 17 final bool maintainState;
18 final bool opaque; 18 final bool opaque;
19 final double Function(BuildContext context)? gestureWidth; 19 final double Function(BuildContext context)? gestureWidth;
20 - final Bindings? binding;  
21 - final List<Bindings> bindings; 20 + final Binding? binding;
  21 + final List<Bind> binds;
22 final CustomTransition? customTransition; 22 final CustomTransition? customTransition;
23 final Duration? transitionDuration; 23 final Duration? transitionDuration;
24 final bool fullscreenDialog; 24 final bool fullscreenDialog;
@@ -56,7 +56,7 @@ class GetPage<T> extends Page<T> { @@ -56,7 +56,7 @@ class GetPage<T> extends Page<T> {
56 this.transitionDuration, 56 this.transitionDuration,
57 this.popGesture, 57 this.popGesture,
58 this.binding, 58 this.binding,
59 - this.bindings = const [], 59 + this.binds = const [],
60 this.transition, 60 this.transition,
61 this.customTransition, 61 this.customTransition,
62 this.fullscreenDialog = false, 62 this.fullscreenDialog = false,
@@ -87,8 +87,8 @@ class GetPage<T> extends Page<T> { @@ -87,8 +87,8 @@ class GetPage<T> extends Page<T> {
87 Alignment? alignment, 87 Alignment? alignment,
88 bool? maintainState, 88 bool? maintainState,
89 bool? opaque, 89 bool? opaque,
90 - Bindings? binding,  
91 - List<Bindings>? bindings, 90 + Binding? binding,
  91 + List<Bind>? binds,
92 CustomTransition? customTransition, 92 CustomTransition? customTransition,
93 Duration? transitionDuration, 93 Duration? transitionDuration,
94 bool? fullscreenDialog, 94 bool? fullscreenDialog,
@@ -117,7 +117,7 @@ class GetPage<T> extends Page<T> { @@ -117,7 +117,7 @@ class GetPage<T> extends Page<T> {
117 maintainState: maintainState ?? this.maintainState, 117 maintainState: maintainState ?? this.maintainState,
118 opaque: opaque ?? this.opaque, 118 opaque: opaque ?? this.opaque,
119 binding: binding ?? this.binding, 119 binding: binding ?? this.binding,
120 - bindings: bindings ?? this.bindings, 120 + binds: binds ?? this.binds,
121 customTransition: customTransition ?? this.customTransition, 121 customTransition: customTransition ?? this.customTransition,
122 transitionDuration: transitionDuration ?? this.transitionDuration, 122 transitionDuration: transitionDuration ?? this.transitionDuration,
123 fullscreenDialog: fullscreenDialog ?? this.fullscreenDialog, 123 fullscreenDialog: fullscreenDialog ?? this.fullscreenDialog,
1 -// import 'package:flutter/material.dart';  
2 -// import 'package:get/get_navigation/src/router_report.dart';  
3 -// import 'package:get/instance_manager.dart';  
4 -  
5 -// class Dependencies {  
6 -// void lazyPut<S>(InstanceBuilderCallback<S> builder,  
7 -// {String? tag, bool fenix = false}) {  
8 -// GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);  
9 -// }  
10 -  
11 -// S call<S>() {  
12 -// return find<S>();  
13 -// }  
14 -  
15 -// Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,  
16 -// {String? tag, bool permanent = false}) async =>  
17 -// GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);  
18 -  
19 -// void create<S>(InstanceBuilderCallback<S> builder,  
20 -// {String? tag, bool permanent = true}) =>  
21 -// GetInstance().create<S>(builder, tag: tag, permanent: permanent);  
22 -  
23 -// S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);  
24 -  
25 -// S put<S>(S dependency,  
26 -// {String? tag,  
27 -// bool permanent = false,  
28 -// InstanceBuilderCallback<S>? builder}) =>  
29 -// GetInstance().put<S>(dependency, tag: tag, permanent: permanent);  
30 -  
31 -// Future<bool> delete<S>({String? tag, bool force = false}) async =>  
32 -// GetInstance().delete<S>(tag: tag, force: force);  
33 -  
34 -// Future<void> deleteAll({bool force = false}) async =>  
35 -// GetInstance().deleteAll(force: force);  
36 -  
37 -// void reloadAll({bool force = false}) => GetInstance().reloadAll(force: force);  
38 -  
39 -// void reload<S>({String? tag, String? key, bool force = false}) =>  
40 -// GetInstance().reload<S>(tag: tag, key: key, force: force);  
41 -  
42 -// bool isRegistered<S>({String? tag}) =>  
43 -// GetInstance().isRegistered<S>(tag: tag);  
44 -  
45 -// bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);  
46 -  
47 -// void replace<P>(P child, {String? tag}) {  
48 -// final info = GetInstance().getInstanceInfo<P>(tag: tag);  
49 -// final permanent = (info.isPermanent ?? false);  
50 -// delete<P>(tag: tag, force: permanent);  
51 -// put(child, tag: tag, permanent: permanent);  
52 -// }  
53 -  
54 -// void lazyReplace<P>(InstanceBuilderCallback<P> builder,  
55 -// {String? tag, bool? fenix}) {  
56 -// final info = GetInstance().getInstanceInfo<P>(tag: tag);  
57 -// final permanent = (info.isPermanent ?? false);  
58 -// delete<P>(tag: tag, force: permanent);  
59 -// lazyPut(builder, tag: tag, fenix: fenix ?? permanent);  
60 -// }  
61 -// }  
62 -  
63 -// abstract class Module extends StatefulWidget {  
64 -// Module({Key? key}) : super(key: key);  
65 -  
66 -// Widget view(BuildContext context);  
67 -  
68 -// void dependencies(Dependencies i);  
69 -  
70 -// @override  
71 -// _ModuleState createState() => _ModuleState();  
72 -// }  
73 -  
74 -// class _ModuleState extends State<Module> {  
75 -// @override  
76 -// void initState() {  
77 -// RouterReportManager.instance.reportCurrentRoute(this);  
78 -// widget.dependencies(Dependencies());  
79 -// super.initState();  
80 -// }  
81 -  
82 -// @override  
83 -// void dispose() {  
84 -// RouterReportManager.instance.reportRouteDispose(this);  
85 -// super.dispose();  
86 -// }  
87 -  
88 -// @override  
89 -// Widget build(BuildContext context) {  
90 -// return widget.view(context);  
91 -// }  
92 -// } 1 +import 'package:flutter/material.dart';
  2 +
  3 +import '../../../instance_manager.dart';
  4 +import '../router_report.dart';
  5 +
  6 +class Dependencies {
  7 + void lazyPut<S>(InstanceBuilderCallback<S> builder,
  8 + {String? tag, bool fenix = false}) {
  9 + GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
  10 + }
  11 +
  12 + S call<S>() {
  13 + return find<S>();
  14 + }
  15 +
  16 + Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
  17 + {String? tag, bool permanent = false}) async =>
  18 + GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
  19 +
  20 + void create<S>(InstanceBuilderCallback<S> builder,
  21 + {String? tag, bool permanent = true}) =>
  22 + GetInstance().create<S>(builder, tag: tag, permanent: permanent);
  23 +
  24 + S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
  25 +
  26 + S put<S>(S dependency,
  27 + {String? tag,
  28 + bool permanent = false,
  29 + InstanceBuilderCallback<S>? builder}) =>
  30 + GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
  31 +
  32 + Future<bool> delete<S>({String? tag, bool force = false}) async =>
  33 + GetInstance().delete<S>(tag: tag, force: force);
  34 +
  35 + Future<void> deleteAll({bool force = false}) async =>
  36 + GetInstance().deleteAll(force: force);
  37 +
  38 + void reloadAll({bool force = false}) => GetInstance().reloadAll(force: force);
  39 +
  40 + void reload<S>({String? tag, String? key, bool force = false}) =>
  41 + GetInstance().reload<S>(tag: tag, key: key, force: force);
  42 +
  43 + bool isRegistered<S>({String? tag}) =>
  44 + GetInstance().isRegistered<S>(tag: tag);
  45 +
  46 + bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
  47 +
  48 + void replace<P>(P child, {String? tag}) {
  49 + final info = GetInstance().getInstanceInfo<P>(tag: tag);
  50 + final permanent = (info.isPermanent ?? false);
  51 + delete<P>(tag: tag, force: permanent);
  52 + put(child, tag: tag, permanent: permanent);
  53 + }
  54 +
  55 + void lazyReplace<P>(InstanceBuilderCallback<P> builder,
  56 + {String? tag, bool? fenix}) {
  57 + final info = GetInstance().getInstanceInfo<P>(tag: tag);
  58 + final permanent = (info.isPermanent ?? false);
  59 + delete<P>(tag: tag, force: permanent);
  60 + lazyPut(builder, tag: tag, fenix: fenix ?? permanent);
  61 + }
  62 +}
  63 +
  64 +abstract class Module extends StatefulWidget {
  65 + Module({Key? key}) : super(key: key);
  66 +
  67 + Widget view(BuildContext context);
  68 +
  69 + void dependencies(Dependencies i);
  70 +
  71 + @override
  72 + _ModuleState createState() => _ModuleState();
  73 +}
  74 +
  75 +class _ModuleState extends State<Module> {
  76 + @override
  77 + void initState() {
  78 + RouterReportManager.instance.reportCurrentRoute(this);
  79 + widget.dependencies(Dependencies());
  80 + super.initState();
  81 + }
  82 +
  83 + @override
  84 + void dispose() {
  85 + RouterReportManager.instance.reportRouteDispose(this);
  86 + super.dispose();
  87 + }
  88 +
  89 + @override
  90 + Widget build(BuildContext context) {
  91 + return widget.view(context);
  92 + }
  93 +}
@@ -77,7 +77,7 @@ abstract class _RouteMiddleware { @@ -77,7 +77,7 @@ abstract class _RouteMiddleware {
77 /// } 77 /// }
78 /// ``` 78 /// ```
79 /// {@end-tool} 79 /// {@end-tool}
80 - List<Bindings>? onBindingsStart(List<Bindings> bindings); 80 + List<Bind>? onBindingsStart(List<Bind> bindings);
81 81
82 /// This function will be called right after the [Bindings] are initialize. 82 /// This function will be called right after the [Bindings] are initialize.
83 GetPageBuilder? onPageBuildStart(GetPageBuilder page); 83 GetPageBuilder? onPageBuildStart(GetPageBuilder page);
@@ -107,7 +107,7 @@ class GetMiddleware implements _RouteMiddleware { @@ -107,7 +107,7 @@ class GetMiddleware implements _RouteMiddleware {
107 GetPage? onPageCalled(GetPage? page) => page; 107 GetPage? onPageCalled(GetPage? page) => page;
108 108
109 @override 109 @override
110 - List<Bindings>? onBindingsStart(List<Bindings>? bindings) => bindings; 110 + List<Bind>? onBindingsStart(List<Bind>? bindings) => bindings;
111 111
112 @override 112 @override
113 GetPageBuilder? onPageBuildStart(GetPageBuilder? page) => page; 113 GetPageBuilder? onPageBuildStart(GetPageBuilder? page) => page;
@@ -155,7 +155,7 @@ class MiddlewareRunner { @@ -155,7 +155,7 @@ class MiddlewareRunner {
155 return to; 155 return to;
156 } 156 }
157 157
158 - List<Bindings>? runOnBindingsStart(List<Bindings>? bindings) { 158 + List<Bind>? runOnBindingsStart(List<Bind>? bindings) {
159 _getMiddlewares().forEach((element) { 159 _getMiddlewares().forEach((element) {
160 bindings = element.onBindingsStart(bindings); 160 bindings = element.onBindingsStart(bindings);
161 }); 161 });
@@ -212,7 +212,7 @@ class PageRedirect { @@ -212,7 +212,7 @@ class PageRedirect {
212 gestureWidth: _r.gestureWidth, 212 gestureWidth: _r.gestureWidth,
213 customTransition: _r.customTransition, 213 customTransition: _r.customTransition,
214 binding: _r.binding, 214 binding: _r.binding,
215 - bindings: _r.bindings, 215 + binds: _r.binds,
216 transitionDuration: 216 transitionDuration:
217 _r.transitionDuration ?? Get.defaultTransitionDuration, 217 _r.transitionDuration ?? Get.defaultTransitionDuration,
218 transition: _r.transition, 218 transition: _r.transition,
@@ -241,7 +241,7 @@ class PageRedirect { @@ -241,7 +241,7 @@ class PageRedirect {
241 opaque: _r.opaque, 241 opaque: _r.opaque,
242 customTransition: _r.customTransition, 242 customTransition: _r.customTransition,
243 binding: _r.binding, 243 binding: _r.binding,
244 - bindings: _r.bindings, 244 + binds: _r.binds,
245 transitionDuration: 245 transitionDuration:
246 _r.transitionDuration ?? Get.defaultTransitionDuration, 246 _r.transitionDuration ?? Get.defaultTransitionDuration,
247 transition: _r.transition, 247 transition: _r.transition,
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter/scheduler.dart';  
3 import '../../../get_instance/src/lifecycle.dart'; 1 import '../../../get_instance/src/lifecycle.dart';
4 2
5 /// Unlike GetxController, which serves to control events on each of its pages, 3 /// Unlike GetxController, which serves to control events on each of its pages,
@@ -8,34 +6,6 @@ import '../../../get_instance/src/lifecycle.dart'; @@ -8,34 +6,6 @@ import '../../../get_instance/src/lifecycle.dart';
8 /// It is ideal for situations where, once started, that service will 6 /// It is ideal for situations where, once started, that service will
9 /// remain in memory, such as Auth control for example. Only way to remove 7 /// remain in memory, such as Auth control for example. Only way to remove
10 /// it is Get.reset(). 8 /// it is Get.reset().
11 -abstract class GetxService extends DisposableInterface with GetxServiceMixin {} 9 +abstract class GetxService with GetLifeCycleMixin, GetxServiceMixin {}
12 10
13 -abstract class DisposableInterface extends GetLifeCycle {  
14 - /// Called immediately after the widget is allocated in memory.  
15 - /// You might use this to initialize something for the controller.  
16 - @override  
17 - @mustCallSuper  
18 - void onInit() {  
19 - super.onInit();  
20 - SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());  
21 - }  
22 -  
23 - /// Called 1 frame after onInit(). It is the perfect place to enter  
24 - /// navigation events, like snackbar, dialogs, or a new route, or  
25 - /// async request.  
26 - @override  
27 - void onReady() {  
28 - super.onReady();  
29 - }  
30 -  
31 - /// Called before [onDelete] method. [onClose] might be used to  
32 - /// dispose resources used by the controller. Like closing events,  
33 - /// or streams before the controller is destroyed.  
34 - /// Or dispose objects that can potentially create some memory leaks,  
35 - /// like TextEditingControllers, AnimationControllers.  
36 - /// Might be useful as well to persist some data on disk.  
37 - @override  
38 - void onClose() {  
39 - super.onClose();  
40 - }  
41 -} 11 +// abstract class DisposableInterface with GetLifeCycleMixin {}
@@ -2,16 +2,17 @@ import 'dart:async'; @@ -2,16 +2,17 @@ import 'dart:async';
2 2
3 import 'package:flutter/foundation.dart'; 3 import 'package:flutter/foundation.dart';
4 import 'package:flutter/widgets.dart'; 4 import 'package:flutter/widgets.dart';
  5 +import 'package:get/get_instance/src/lifecycle.dart';
5 6
6 import '../../../get_core/get_core.dart'; 7 import '../../../get_core/get_core.dart';
7 import '../../../get_instance/src/get_instance.dart'; 8 import '../../../get_instance/src/get_instance.dart';
8 import '../../../get_rx/src/rx_types/rx_types.dart'; 9 import '../../../get_rx/src/rx_types/rx_types.dart';
9 import '../../get_state_manager.dart'; 10 import '../../get_state_manager.dart';
10 11
11 -typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function( 12 +typedef GetXControllerBuilder<T extends GetLifeCycleMixin> = Widget Function(
12 T controller); 13 T controller);
13 14
14 -class GetX<T extends DisposableInterface> extends StatefulWidget { 15 +class GetX<T extends GetLifeCycleMixin> extends StatefulWidget {
15 final GetXControllerBuilder<T> builder; 16 final GetXControllerBuilder<T> builder;
16 final bool global; 17 final bool global;
17 final bool autoRemove; 18 final bool autoRemove;
@@ -54,7 +55,7 @@ class GetX<T extends DisposableInterface> extends StatefulWidget { @@ -54,7 +55,7 @@ class GetX<T extends DisposableInterface> extends StatefulWidget {
54 GetXState<T> createState() => GetXState<T>(); 55 GetXState<T> createState() => GetXState<T>();
55 } 56 }
56 57
57 -class GetXState<T extends DisposableInterface> extends State<GetX<T>> { 58 +class GetXState<T extends GetLifeCycleMixin> extends State<GetX<T>> {
58 final _observer = RxNotifier(); 59 final _observer = RxNotifier();
59 T? controller; 60 T? controller;
60 bool? _isCreator = false; 61 bool? _isCreator = false;
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 -import 'package:flutter/scheduler.dart';  
4 3
5 import '../../../instance_manager.dart'; 4 import '../../../instance_manager.dart';
6 import '../../get_state_manager.dart'; 5 import '../../get_state_manager.dart';
@@ -118,15 +117,8 @@ extension ReactiveT<T> on T { @@ -118,15 +117,8 @@ extension ReactiveT<T> on T {
118 117
119 typedef Condition = bool Function(); 118 typedef Condition = bool Function();
120 119
121 -abstract class GetNotifier<T> extends Value<T> with GetLifeCycleBase { 120 +abstract class GetNotifier<T> extends Value<T> with GetLifeCycleMixin {
122 GetNotifier(T initial) : super(initial); 121 GetNotifier(T initial) : super(initial);
123 -  
124 - @override  
125 - @mustCallSuper  
126 - void onInit() {  
127 - super.onInit();  
128 - SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());  
129 - }  
130 } 122 }
131 123
132 extension StateExt<T> on StateMixin<T> { 124 extension StateExt<T> on StateMixin<T> {
@@ -56,15 +56,6 @@ class _ObxState extends State<ObxWidget> { @@ -56,15 +56,6 @@ class _ObxState extends State<ObxWidget> {
56 RxInterface.notifyChildren(_observer, widget.build); 56 RxInterface.notifyChildren(_observer, widget.build);
57 } 57 }
58 58
59 -  
60 -  
61 -  
62 -  
63 -  
64 -  
65 -  
66 -  
67 -  
68 /// The simplest reactive widget in GetX. 59 /// The simplest reactive widget in GetX.
69 /// 60 ///
70 /// Just pass your Rx variable in the root scope of the callback to have it 61 /// Just pass your Rx variable in the root scope of the callback to have it
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
4 import 'package:flutter/material.dart'; 4 import 'package:flutter/material.dart';
5 import 'package:flutter/scheduler.dart'; 5 import 'package:flutter/scheduler.dart';
6 6
  7 +import '../../../get_instance/src/lifecycle.dart';
7 import '../../get_state_manager.dart'; 8 import '../../get_state_manager.dart';
8 9
9 /// Used like `SingleTickerProviderMixin` but only with Get Controllers. 10 /// Used like `SingleTickerProviderMixin` but only with Get Controllers.
@@ -196,7 +197,7 @@ class _WidgetTicker extends Ticker { @@ -196,7 +197,7 @@ class _WidgetTicker extends Ticker {
196 /// } 197 /// }
197 /// ... 198 /// ...
198 /// ``` 199 /// ```
199 -mixin SingleGetTickerProviderMixin on DisposableInterface 200 +mixin SingleGetTickerProviderMixin on GetLifeCycleMixin
200 implements TickerProvider { 201 implements TickerProvider {
201 @override 202 @override
202 Ticker createTicker(TickerCallback onTick) => Ticker(onTick); 203 Ticker createTicker(TickerCallback onTick) => Ticker(onTick);
1 // ignore: prefer_mixin 1 // ignore: prefer_mixin
2 import 'package:flutter/widgets.dart'; 2 import 'package:flutter/widgets.dart';
3 -import '../../../instance_manager.dart';  
4 3
5 -import '../rx_flutter/rx_disposable.dart'; 4 +import '../../../instance_manager.dart';
6 import '../rx_flutter/rx_notifier.dart'; 5 import '../rx_flutter/rx_notifier.dart';
7 import 'list_notifier.dart'; 6 import 'list_notifier.dart';
8 7
9 // ignore: prefer_mixin 8 // ignore: prefer_mixin
10 -abstract class GetxController extends DisposableInterface  
11 - with ListenableMixin, ListNotifierMixin { 9 +abstract class GetxController extends Listenable
  10 + with GetLifeCycleMixin, ListNotifierMixin {
12 /// Rebuilds `GetBuilder` each time you call `update()`; 11 /// Rebuilds `GetBuilder` each time you call `update()`;
13 /// Can take a List of [ids], that will only update the matching 12 /// Can take a List of [ids], that will only update the matching
14 /// `GetBuilder( id: )`, 13 /// `GetBuilder( id: )`,
@@ -28,7 +27,7 @@ abstract class GetxController extends DisposableInterface @@ -28,7 +27,7 @@ abstract class GetxController extends DisposableInterface
28 } 27 }
29 } 28 }
30 29
31 -mixin ScrollMixin on GetLifeCycleBase { 30 +mixin ScrollMixin on GetLifeCycleMixin {
32 final ScrollController scroll = ScrollController(); 31 final ScrollController scroll = ScrollController();
33 32
34 @override 33 @override
@@ -72,7 +71,7 @@ mixin ScrollMixin on GetLifeCycleBase { @@ -72,7 +71,7 @@ mixin ScrollMixin on GetLifeCycleBase {
72 } 71 }
73 } 72 }
74 73
75 -abstract class RxController extends DisposableInterface {} 74 +abstract class RxController with GetLifeCycleMixin {}
76 75
77 abstract class SuperController<T> extends FullLifeCycleController 76 abstract class SuperController<T> extends FullLifeCycleController
78 with FullLifeCycleMixin, StateMixin<T> {} 77 with FullLifeCycleMixin, StateMixin<T> {}
@@ -67,7 +67,7 @@ class GetResponsiveView<T> extends GetView<T> with GetResponsiveMixin { @@ -67,7 +67,7 @@ class GetResponsiveView<T> extends GetView<T> with GetResponsiveMixin {
67 super(key: key); 67 super(key: key);
68 } 68 }
69 69
70 -class GetResponsiveWidget<T extends GetLifeCycleBase?> extends GetWidget<T> 70 +class GetResponsiveWidget<T extends GetLifeCycleMixin> extends GetWidget<T>
71 with GetResponsiveMixin { 71 with GetResponsiveMixin {
72 @override 72 @override
73 final bool alwaysUseBuilder; 73 final bool alwaysUseBuilder;
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 2
3 -import '../../../get_instance/src/get_instance.dart';  
4 import '../../../instance_manager.dart'; 3 import '../../../instance_manager.dart';
5 import '../../get_state_manager.dart'; 4 import '../../get_state_manager.dart';
6 5
7 -typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function( 6 +typedef InitBuilder<T> = T Function();
  7 +
  8 +typedef GetControllerBuilder<T extends GetLifeCycleMixin> = Widget Function(
8 T controller); 9 T controller);
9 10
10 extension WatchExt on BuildContext { 11 extension WatchExt on BuildContext {
11 T listen<T extends GetxController>() { 12 T listen<T extends GetxController>() {
12 - return Scope.of(this, rebuild: true); 13 + return Bind.of(this, rebuild: true);
13 } 14 }
14 } 15 }
15 16
16 extension ReadExt on BuildContext { 17 extension ReadExt on BuildContext {
17 - T find<T extends GetxController>() {  
18 - return Scope.of(this); 18 + T get<T extends GetxController>() {
  19 + return Bind.of(this);
19 } 20 }
20 } 21 }
21 22
22 // extension FilterExt on BuildContext { 23 // extension FilterExt on BuildContext {
23 // T filter<T extends GetxController>(Object Function(T value)? filter) { 24 // T filter<T extends GetxController>(Object Function(T value)? filter) {
24 -// return Scope.of(this, filter: filter, rebuild: true); 25 +// return Bind.of(this, filter: filter, rebuild: true);
25 // } 26 // }
26 // } 27 // }
27 28
@@ -33,10 +34,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget { @@ -33,10 +34,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
33 final bool autoRemove; 34 final bool autoRemove;
34 final bool assignId; 35 final bool assignId;
35 final Object Function(T value)? filter; 36 final Object Function(T value)? filter;
36 - final void Function(ScopeElement<T> state)? initState, 37 + final void Function(BindElement<T> state)? initState,
37 dispose, 38 dispose,
38 didChangeDependencies; 39 didChangeDependencies;
39 - final void Function(Scope<T> oldWidget, ScopeElement<T> state)? 40 + final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
40 didUpdateWidget; 41 didUpdateWidget;
41 final T? init; 42 final T? init;
42 43
@@ -58,8 +59,8 @@ class GetBuilder<T extends GetxController> extends StatelessWidget { @@ -58,8 +59,8 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
58 59
59 @override 60 @override
60 Widget build(BuildContext context) { 61 Widget build(BuildContext context) {
61 - return Scope<T>(  
62 - init: init, 62 + return BindWrapper(
  63 + init: init == null ? null : () => init!,
63 global: global, 64 global: global,
64 autoRemove: autoRemove, 65 autoRemove: autoRemove,
65 assignId: assignId, 66 assignId: assignId,
@@ -71,7 +72,7 @@ class GetBuilder<T extends GetxController> extends StatelessWidget { @@ -71,7 +72,7 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
71 didChangeDependencies: didChangeDependencies, 72 didChangeDependencies: didChangeDependencies,
72 didUpdateWidget: didUpdateWidget, 73 didUpdateWidget: didUpdateWidget,
73 child: Builder(builder: (context) { 74 child: Builder(builder: (context) {
74 - final controller = Scope.of<T>(context, rebuild: true); 75 + final controller = Bind.of<T>(context, rebuild: true);
75 return builder(controller); 76 return builder(controller);
76 }), 77 }),
77 ); 78 );
@@ -79,14 +80,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget { @@ -79,14 +80,10 @@ class GetBuilder<T extends GetxController> extends StatelessWidget {
79 } 80 }
80 } 81 }
81 82
82 -class Scope<T extends GetxController> extends InheritedWidget {  
83 - /// Create an inherited widget that updates its dependents when [controller]  
84 - /// sends notifications.  
85 - ///  
86 - /// The [child] argument is required  
87 - const Scope({ 83 +abstract class Bind<T> extends StatelessWidget {
  84 + const Bind({
88 Key? key, 85 Key? key,
89 - required Widget child, 86 + required this.child,
90 this.init, 87 this.init,
91 this.global = true, 88 this.global = true,
92 this.autoRemove = true, 89 this.autoRemove = true,
@@ -98,21 +95,9 @@ class Scope<T extends GetxController> extends InheritedWidget { @@ -98,21 +95,9 @@ class Scope<T extends GetxController> extends InheritedWidget {
98 this.id, 95 this.id,
99 this.didChangeDependencies, 96 this.didChangeDependencies,
100 this.didUpdateWidget, 97 this.didUpdateWidget,
101 - }) : super(key: key, child: child); 98 + }) : super(key: key);
102 99
103 - /// The [Listenable] object to which to listen.  
104 - ///  
105 - /// Whenever this object sends change notifications, the dependents of this  
106 - /// widget are triggered.  
107 - ///  
108 - /// By default, whenever the [controller] is changed (including when changing to  
109 - /// or from null), if the old controller is not equal to the new controller (as  
110 - /// determined by the `==` operator), notifications are sent. This behavior  
111 - /// can be overridden by overriding [updateShouldNotify].  
112 - ///  
113 - /// While the [controller] is null, no notifications are sent, since the null  
114 - /// object cannot itself send notifications.  
115 - final T? init; 100 + final InitBuilder<T>? init;
116 101
117 final bool global; 102 final bool global;
118 final Object? id; 103 final Object? id;
@@ -120,19 +105,125 @@ class Scope<T extends GetxController> extends InheritedWidget { @@ -120,19 +105,125 @@ class Scope<T extends GetxController> extends InheritedWidget {
120 final bool autoRemove; 105 final bool autoRemove;
121 final bool assignId; 106 final bool assignId;
122 final Object Function(T value)? filter; 107 final Object Function(T value)? filter;
123 - final void Function(ScopeElement<T> state)? initState, 108 + final void Function(BindElement<T> state)? initState,
124 dispose, 109 dispose,
125 didChangeDependencies; 110 didChangeDependencies;
126 - final void Function(Scope<T> oldWidget, ScopeElement<T> state)? 111 + final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
127 didUpdateWidget; 112 didUpdateWidget;
128 113
  114 + final Widget? child;
  115 +
  116 + static Bind put<S extends GetxController>(S dependency,
  117 + {String? tag,
  118 + bool permanent = false,
  119 + InstanceBuilderCallback<S>? builder}) {
  120 + Get.put<S>(dependency, tag: tag, permanent: permanent, builder: builder);
  121 + return _FactoryBind<S>(
  122 + autoRemove: permanent,
  123 + assignId: true,
  124 + tag: tag,
  125 + );
  126 + }
  127 +
  128 + static Bind lazyPut<S>(
  129 + InstanceBuilderCallback<S> builder, {
  130 + String? tag,
  131 + bool fenix = false,
  132 + }) {
  133 + Get.lazyPut<S>(builder, tag: tag, fenix: fenix);
  134 + return _FactoryBind<S>(
  135 + tag: tag,
  136 + );
  137 + }
  138 +
  139 + static Bind create<S extends GetxController>(
  140 + InstanceBuilderCallback<S> builder,
  141 + {String? tag,
  142 + bool permanent = true}) {
  143 + Get.create<S>(builder, tag: tag, permanent: permanent);
  144 + return _FactoryBind<S>(
  145 + tag: tag,
  146 + );
  147 + }
  148 +
  149 + static S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
  150 +
  151 + static Future<bool> delete<S>({String? tag, bool force = false}) async =>
  152 + GetInstance().delete<S>(tag: tag, force: force);
  153 +
  154 + static Future<void> deleteAll({bool force = false}) async =>
  155 + GetInstance().deleteAll(force: force);
  156 +
  157 + static void reloadAll({bool force = false}) =>
  158 + GetInstance().reloadAll(force: force);
  159 +
  160 + static void reload<S>({String? tag, String? key, bool force = false}) =>
  161 + GetInstance().reload<S>(tag: tag, key: key, force: force);
  162 +
  163 + static bool isRegistered<S>({String? tag}) =>
  164 + GetInstance().isRegistered<S>(tag: tag);
  165 +
  166 + static bool isPrepared<S>({String? tag}) =>
  167 + GetInstance().isPrepared<S>(tag: tag);
  168 +
  169 + static void replace<P>(P child, {String? tag}) {
  170 + final info = GetInstance().getInstanceInfo<P>(tag: tag);
  171 + final permanent = (info.isPermanent ?? false);
  172 + delete<P>(tag: tag, force: permanent);
  173 + GetInstance().put(child, tag: tag, permanent: permanent);
  174 + }
  175 +
  176 + static void lazyReplace<P>(InstanceBuilderCallback<P> builder,
  177 + {String? tag, bool? fenix}) {
  178 + final info = GetInstance().getInstanceInfo<P>(tag: tag);
  179 + final permanent = (info.isPermanent ?? false);
  180 + delete<P>(tag: tag, force: permanent);
  181 + GetInstance().lazyPut(builder, tag: tag, fenix: fenix ?? permanent);
  182 + }
  183 +
  184 + factory Bind.builder({
  185 + Widget? child,
  186 + InitBuilder<T>? init,
  187 + bool global = true,
  188 + bool autoRemove = true,
  189 + bool assignId = false,
  190 + Object Function(T value)? filter,
  191 + String? tag,
  192 + Object? id,
  193 + void Function(BindElement<T> state)? initState,
  194 + void Function(BindElement<T> state)? dispose,
  195 + void Function(BindElement<T> state)? didChangeDependencies,
  196 + void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
  197 + didUpdateWidget,
  198 + }) =>
  199 + _FactoryBind<T>(
  200 + // key: key,
  201 + init: init,
  202 + global: global,
  203 + autoRemove: autoRemove,
  204 + assignId: assignId,
  205 + initState: initState,
  206 + filter: filter,
  207 + tag: tag,
  208 + dispose: dispose,
  209 + id: id,
  210 + didChangeDependencies: didChangeDependencies,
  211 + didUpdateWidget: didUpdateWidget,
  212 + child: child,
  213 + );
  214 +
129 static T of<T extends GetxController>( 215 static T of<T extends GetxController>(
130 BuildContext context, { 216 BuildContext context, {
131 bool rebuild = false, 217 bool rebuild = false,
132 // Object Function(T value)? filter, 218 // Object Function(T value)? filter,
133 }) { 219 }) {
134 - final inheritedElement = context  
135 - .getElementForInheritedWidgetOfExactType<Scope<T>>() as ScopeElement<T>; 220 + final inheritedElement =
  221 + context.getElementForInheritedWidgetOfExactType<BindWrapper<T>>()
  222 + as BindElement<T>?;
  223 +
  224 + if (inheritedElement == null) {
  225 + throw BindError(controller: '$T', tag: null);
  226 + }
136 227
137 if (rebuild) { 228 if (rebuild) {
138 // var newFilter = filter?.call(inheritedElement.controller!); 229 // var newFilter = filter?.call(inheritedElement.controller!);
@@ -145,15 +236,159 @@ class Scope<T extends GetxController> extends InheritedWidget { @@ -145,15 +236,159 @@ class Scope<T extends GetxController> extends InheritedWidget {
145 236
146 var widget = inheritedElement.controller; 237 var widget = inheritedElement.controller;
147 238
148 - if (widget == null) {  
149 - throw 'Error: Could not find the correct dependency.';  
150 - } else {  
151 return widget; 239 return widget;
152 } 240 }
  241 +
  242 + @factory
  243 + Bind<T> _copyWithChild(Widget child);
  244 +}
  245 +
  246 +class _FactoryBind<T> extends Bind<T> {
  247 + @override
  248 + final InitBuilder<T>? init;
  249 +
  250 + @override
  251 + final bool global;
  252 + @override
  253 + final Object? id;
  254 + @override
  255 + final String? tag;
  256 + @override
  257 + final bool autoRemove;
  258 + @override
  259 + final bool assignId;
  260 + @override
  261 + final Object Function(T value)? filter;
  262 +
  263 + @override
  264 + final void Function(BindElement<T> state)? initState,
  265 + dispose,
  266 + didChangeDependencies;
  267 + @override
  268 + final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
  269 + didUpdateWidget;
  270 +
  271 + @override
  272 + final Widget? child;
  273 +
  274 + const _FactoryBind({
  275 + Key? key,
  276 + this.child,
  277 + this.init,
  278 + this.global = true,
  279 + this.autoRemove = true,
  280 + this.assignId = false,
  281 + this.initState,
  282 + this.filter,
  283 + this.tag,
  284 + this.dispose,
  285 + this.id,
  286 + this.didChangeDependencies,
  287 + this.didUpdateWidget,
  288 + }) : super(key: key, child: child);
  289 +
  290 + @override
  291 + Bind<T> _copyWithChild(Widget child) {
  292 + return Bind<T>.builder(
  293 + init: init,
  294 + global: global,
  295 + autoRemove: autoRemove,
  296 + assignId: assignId,
  297 + initState: initState,
  298 + filter: filter,
  299 + tag: tag,
  300 + dispose: dispose,
  301 + id: id,
  302 + didChangeDependencies: didChangeDependencies,
  303 + didUpdateWidget: didUpdateWidget,
  304 + child: child,
  305 + );
153 } 306 }
154 307
155 @override 308 @override
156 - bool updateShouldNotify(Scope<T> oldWidget) { 309 + Widget build(BuildContext context) {
  310 + return BindWrapper<T>(
  311 + init: init,
  312 + global: global,
  313 + autoRemove: autoRemove,
  314 + assignId: assignId,
  315 + initState: initState,
  316 + filter: filter,
  317 + tag: tag,
  318 + dispose: dispose,
  319 + id: id,
  320 + didChangeDependencies: didChangeDependencies,
  321 + didUpdateWidget: didUpdateWidget,
  322 + child: child!,
  323 + );
  324 + }
  325 +}
  326 +
  327 +class Binds extends StatelessWidget {
  328 + final List<Bind<dynamic>> binds;
  329 + final Widget child;
  330 +
  331 + Binds({
  332 + Key? key,
  333 + required this.binds,
  334 + required this.child,
  335 + }) : assert(binds.isNotEmpty),
  336 + super(key: key);
  337 +
  338 + @override
  339 + Widget build(BuildContext context) =>
  340 + binds.reversed.fold(child, (acc, e) => e._copyWithChild(acc));
  341 +}
  342 +
  343 +class BindWrapper<T> extends InheritedWidget {
  344 + /// Create an inherited widget that updates its dependents when [controller]
  345 + /// sends notifications.
  346 + ///
  347 + /// The [child] argument is required
  348 + const BindWrapper({
  349 + Key? key,
  350 + required Widget child,
  351 + this.init,
  352 + this.global = true,
  353 + this.autoRemove = true,
  354 + this.assignId = false,
  355 + this.initState,
  356 + this.filter,
  357 + this.tag,
  358 + this.dispose,
  359 + this.id,
  360 + this.didChangeDependencies,
  361 + this.didUpdateWidget,
  362 + }) : super(key: key, child: child);
  363 +
  364 + /// The [Listenable] object to which to listen.
  365 + ///
  366 + /// Whenever this object sends change notifications, the dependents of this
  367 + /// widget are triggered.
  368 + ///
  369 + /// By default, whenever the [controller] is changed (including when changing to
  370 + /// or from null), if the old controller is not equal to the new controller (as
  371 + /// determined by the `==` operator), notifications are sent. This behavior
  372 + /// can be overridden by overriding [updateShouldNotify].
  373 + ///
  374 + /// While the [controller] is null, no notifications are sent, since the null
  375 + /// object cannot itself send notifications.
  376 + final InitBuilder<T>? init;
  377 +
  378 + final bool global;
  379 + final Object? id;
  380 + final String? tag;
  381 + final bool autoRemove;
  382 + final bool assignId;
  383 + final Object Function(T value)? filter;
  384 + final void Function(BindElement<T> state)? initState,
  385 + dispose,
  386 + didChangeDependencies;
  387 + final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
  388 + didUpdateWidget;
  389 +
  390 + @override
  391 + bool updateShouldNotify(BindWrapper<T> oldWidget) {
157 return oldWidget.id != id || 392 return oldWidget.id != id ||
158 oldWidget.global != global || 393 oldWidget.global != global ||
159 oldWidget.autoRemove != autoRemove || 394 oldWidget.autoRemove != autoRemove ||
@@ -161,18 +396,37 @@ class Scope<T extends GetxController> extends InheritedWidget { @@ -161,18 +396,37 @@ class Scope<T extends GetxController> extends InheritedWidget {
161 } 396 }
162 397
163 @override 398 @override
164 - InheritedElement createElement() => ScopeElement<T>(this); 399 + InheritedElement createElement() => BindElement<T>(this);
165 } 400 }
166 401
167 -/// The ScopeElement is responsible for injecting dependencies into the widget 402 +/// The BindElement is responsible for injecting dependencies into the widget
168 /// tree so that they can be observed 403 /// tree so that they can be observed
169 -class ScopeElement<T extends GetxController> extends InheritedElement {  
170 - ScopeElement(Scope<T> widget) : super(widget) { 404 +class BindElement<T> extends InheritedElement {
  405 + BindElement(BindWrapper<T> widget) : super(widget) {
171 initState(); 406 initState();
172 } 407 }
173 408
174 - T? controller; 409 + InitBuilder<T>? _controllerBuilder;
  410 +
  411 + T? _controller;
  412 +
  413 + T get controller {
  414 + print('get controller $T');
  415 + if (_controller == null) {
  416 + _controller = _controllerBuilder?.call();
  417 + _subscribeToController();
  418 + if (_controller == null) {
  419 + throw BindError(controller: T, tag: widget.tag);
  420 + }
  421 + return _controller!;
  422 + } else {
  423 + return _controller!;
  424 + }
  425 + }
  426 +
175 bool? _isCreator = false; 427 bool? _isCreator = false;
  428 + bool? _needStart = false;
  429 + bool _wasStarted = false;
176 VoidCallback? _remove; 430 VoidCallback? _remove;
177 Object? _filter; 431 Object? _filter;
178 432
@@ -188,42 +442,50 @@ class ScopeElement<T extends GetxController> extends InheritedElement { @@ -188,42 +442,50 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
188 } else { 442 } else {
189 _isCreator = false; 443 _isCreator = false;
190 } 444 }
191 - controller = GetInstance().find<T>(tag: widget.tag); 445 +
  446 + _controllerBuilder = () => GetInstance().find<T>(tag: widget.tag);
192 } else { 447 } else {
193 - controller = widget.init; 448 + _controllerBuilder = widget.init;
194 _isCreator = true; 449 _isCreator = true;
195 - GetInstance().put<T>(controller!, tag: widget.tag); 450 + GetInstance().lazyPut<T>(_controllerBuilder!, tag: widget.tag);
196 } 451 }
197 } else { 452 } else {
198 - controller = widget.init; 453 + _controllerBuilder = widget.init;
199 _isCreator = true; 454 _isCreator = true;
200 - controller?.onStart(); 455 + _needStart = true;
201 } 456 }
202 -  
203 - if (widget.filter != null) {  
204 - _filter = widget.filter!(controller!);  
205 - }  
206 -  
207 - _subscribeToController();  
208 } 457 }
209 458
210 /// Register to listen Controller's events. 459 /// Register to listen Controller's events.
211 /// It gets a reference to the remove() callback, to delete the 460 /// It gets a reference to the remove() callback, to delete the
212 /// setState "link" from the Controller. 461 /// setState "link" from the Controller.
213 void _subscribeToController() { 462 void _subscribeToController() {
  463 + if (widget.filter != null) {
  464 + _filter = widget.filter!(_controller!);
  465 + }
  466 + final filter = _filter != null ? _filterUpdate : getUpdate;
  467 + final localController = _controller;
  468 +
  469 + if (_needStart == true && localController is GetLifeCycleMixin) {
  470 + localController.onStart();
  471 + _needStart = false;
  472 + _wasStarted = true;
  473 + }
  474 +
  475 + if (localController is GetxController) {
214 _remove?.call(); 476 _remove?.call();
215 _remove = (widget.id == null) 477 _remove = (widget.id == null)
216 - ? controller?.addListener(  
217 - _filter != null ? _filterUpdate : getUpdate,  
218 - )  
219 - : controller?.addListenerId(  
220 - widget.id,  
221 - _filter != null ? _filterUpdate : getUpdate,  
222 - ); 478 + ? localController.addListener(filter)
  479 + : localController.addListenerId(widget.id, filter);
  480 + } else if (localController is Listenable) {
  481 + _remove?.call();
  482 + localController.addListener(filter);
  483 + _remove = () => localController.removeListener(filter);
  484 + }
223 } 485 }
224 486
225 void _filterUpdate() { 487 void _filterUpdate() {
226 - var newFilter = widget.filter!(controller!); 488 + var newFilter = widget.filter!(_controller!);
227 if (newFilter != _filter) { 489 if (newFilter != _filter) {
228 _filter = newFilter; 490 _filter = newFilter;
229 getUpdate(); 491 getUpdate();
@@ -239,23 +501,25 @@ class ScopeElement<T extends GetxController> extends InheritedElement { @@ -239,23 +501,25 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
239 } 501 }
240 502
241 _remove?.call(); 503 _remove?.call();
242 -  
243 - controller = null; 504 + _controller = null;
244 _isCreator = null; 505 _isCreator = null;
245 _remove = null; 506 _remove = null;
246 _filter = null; 507 _filter = null;
  508 + _needStart = null;
  509 + _controllerBuilder = null;
  510 + _controller = null;
247 } 511 }
248 512
249 @override 513 @override
250 - Scope<T> get widget => super.widget as Scope<T>; 514 + BindWrapper<T> get widget => super.widget as BindWrapper<T>;
251 515
252 var _dirty = false; 516 var _dirty = false;
253 517
254 @override 518 @override
255 - void update(Scope<T> newWidget) { 519 + void update(BindWrapper<T> newWidget) {
256 final oldNotifier = widget.id; 520 final oldNotifier = widget.id;
257 final newNotifier = newWidget.id; 521 final newNotifier = newWidget.id;
258 - if (oldNotifier != newNotifier) { 522 + if (oldNotifier != newNotifier && _wasStarted) {
259 _subscribeToController(); 523 _subscribeToController();
260 } 524 }
261 widget.didUpdateWidget?.call(widget, this); 525 widget.didUpdateWidget?.call(widget, this);
@@ -282,7 +546,7 @@ class ScopeElement<T extends GetxController> extends InheritedElement { @@ -282,7 +546,7 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
282 } 546 }
283 547
284 @override 548 @override
285 - void notifyClients(Scope<T> oldWidget) { 549 + void notifyClients(BindWrapper<T> oldWidget) {
286 super.notifyClients(oldWidget); 550 super.notifyClients(oldWidget);
287 _dirty = false; 551 _dirty = false;
288 } 552 }
@@ -293,3 +557,32 @@ class ScopeElement<T extends GetxController> extends InheritedElement { @@ -293,3 +557,32 @@ class ScopeElement<T extends GetxController> extends InheritedElement {
293 super.unmount(); 557 super.unmount();
294 } 558 }
295 } 559 }
  560 +
  561 +class BindError<T> extends Error {
  562 + /// The type of the class the user tried to retrieve
  563 + final T controller;
  564 + final String? tag;
  565 +
  566 + /// Creates a [BindError]
  567 + BindError({required this.controller, required this.tag});
  568 +
  569 + @override
  570 + String toString() {
  571 + if (controller == 'dynamic') {
  572 + return '''Error: please specify type [<T>] when calling context.listen<T>() or context.find<T>() method.''';
  573 + }
  574 +
  575 + return '''Error: No Bind<$controller> ancestor found. To fix this, please add a Bind<$controller> widget ancestor to the current context.
  576 + ''';
  577 + }
  578 +}
  579 +
  580 +/// [Binding] should be extended.
  581 +/// When using `GetMaterialApp`, all `GetPage`s and navigation
  582 +/// methods (like Get.to()) have a `binding` property that takes an
  583 +/// instance of Bindings to manage the
  584 +/// dependencies() (via Get.put()) for the Route you are opening.
  585 +// ignore: one_member_abstracts
  586 +abstract class Binding {
  587 + List<Bind> dependencies();
  588 +}
@@ -47,7 +47,7 @@ abstract class GetView<T> extends StatelessWidget { @@ -47,7 +47,7 @@ abstract class GetView<T> extends StatelessWidget {
47 /// GetWidget is perfect to multiples instance of a same controller. Each 47 /// GetWidget is perfect to multiples instance of a same controller. Each
48 /// GetWidget will have your own controller, and will be call events as `onInit` 48 /// GetWidget will have your own controller, and will be call events as `onInit`
49 /// and `onClose` when the controller get in/get out on memory. 49 /// and `onClose` when the controller get in/get out on memory.
50 -abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache { 50 +abstract class GetWidget<S extends GetLifeCycleMixin> extends GetWidgetCache {
51 const GetWidget({Key? key}) : super(key: key); 51 const GetWidget({Key? key}) : super(key: key);
52 52
53 @protected 53 @protected
@@ -57,7 +57,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache { @@ -57,7 +57,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache {
57 57
58 // static final _cache = <GetWidget, GetLifeCycleBase>{}; 58 // static final _cache = <GetWidget, GetLifeCycleBase>{};
59 59
60 - static final _cache = Expando<GetLifeCycleBase>(); 60 + static final _cache = Expando<GetLifeCycleMixin>();
61 61
62 @protected 62 @protected
63 Widget build(BuildContext context); 63 Widget build(BuildContext context);
@@ -66,7 +66,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache { @@ -66,7 +66,7 @@ abstract class GetWidget<S extends GetLifeCycleBase?> extends GetWidgetCache {
66 WidgetCache createWidgetCache() => _GetCache<S>(); 66 WidgetCache createWidgetCache() => _GetCache<S>();
67 } 67 }
68 68
69 -class _GetCache<S extends GetLifeCycleBase?> extends WidgetCache<GetWidget<S>> { 69 +class _GetCache<S extends GetLifeCycleMixin> extends WidgetCache<GetWidget<S>> {
70 S? _controller; 70 S? _controller;
71 bool _isCreator = false; 71 bool _isCreator = false;
72 InstanceInfo? info; 72 InstanceInfo? info;
@@ -88,7 +88,7 @@ class _GetCache<S extends GetLifeCycleBase?> extends WidgetCache<GetWidget<S>> { @@ -88,7 +88,7 @@ class _GetCache<S extends GetLifeCycleBase?> extends WidgetCache<GetWidget<S>> {
88 void onClose() { 88 void onClose() {
89 if (_isCreator) { 89 if (_isCreator) {
90 Get.asap(() { 90 Get.asap(() {
91 - widget!.controller!.onDelete(); 91 + widget!.controller.onDelete();
92 Get.log('"${widget!.controller.runtimeType}" onClose() called'); 92 Get.log('"${widget!.controller.runtimeType}" onClose() called');
93 Get.log('"${widget!.controller.runtimeType}" deleted from memory'); 93 Get.log('"${widget!.controller.runtimeType}" deleted from memory');
94 GetWidget._cache[widget!] = null; 94 GetWidget._cache[widget!] = null;
@@ -9,10 +9,10 @@ typedef Disposer = void Function(); @@ -9,10 +9,10 @@ typedef Disposer = void Function();
9 // if it brings overhead the extra call, 9 // if it brings overhead the extra call,
10 typedef GetStateUpdate = void Function(); 10 typedef GetStateUpdate = void Function();
11 11
12 -class ListNotifier extends Listenable with ListenableMixin, ListNotifierMixin {} 12 +class ListNotifier extends Listenable with ListNotifierMixin {}
13 13
14 -mixin ListenableMixin implements Listenable {}  
15 -mixin ListNotifierMixin on ListenableMixin { 14 +//mixin ListenableMixin implements Listenable {}
  15 +mixin ListNotifierMixin on Listenable {
16 // int _version = 0; 16 // int _version = 0;
17 // int _microtask = 0; 17 // int _microtask = 0;
18 18
@@ -8,10 +8,10 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget { @@ -8,10 +8,10 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget {
8 final bool global; 8 final bool global;
9 final String? id; 9 final String? id;
10 final bool autoRemove; 10 final bool autoRemove;
11 - final void Function(ScopeElement<T> state)? initState, 11 + final void Function(BindElement<T> state)? initState,
12 dispose, 12 dispose,
13 didChangeDependencies; 13 didChangeDependencies;
14 - final void Function(Scope<T> oldWidget, ScopeElement<T> state)? 14 + final void Function(BindWrapper<T> oldWidget, BindElement<T> state)?
15 didUpdateWidget; 15 didUpdateWidget;
16 final T? init; 16 final T? init;
17 17
@@ -12,7 +12,7 @@ class Mock { @@ -12,7 +12,7 @@ class Mock {
12 } 12 }
13 } 13 }
14 14
15 -abstract class MyController extends GetLifeCycle {} 15 +abstract class MyController with GetLifeCycleMixin {}
16 16
17 class DisposableController extends MyController {} 17 class DisposableController extends MyController {}
18 18