modular icon indicating copy to clipboard operation
modular copied to clipboard

WidgetModule use in Version 6

Open manoj-simform opened this issue 2 years ago • 5 comments

Describe the question How we can achieve WidgetModule class functionality in version 6? In the documentation, I am not able to find a way to migrate from version 5 to 6 in this case:

class TestModule extends WidgetModule {
  TestModule({super.key});

  @override
  List<Bind<Object>> get binds => [];

  @override
  Widget get view => const MyWidget();
}

Any help would be appreciated. Thank you.

manoj-simform avatar Oct 19 '23 05:10 manoj-simform

@manojSimfrom, version 6 removed WidgetModule, ModularState e AsyncBind.

eduardoflorence avatar Oct 19 '23 18:10 eduardoflorence

@eduardoflorence Thank you for the replay. But I want to know the alternative to this or how we can achieve it in version 6.

manoj-simform avatar Oct 20 '23 06:10 manoj-simform

Same question here. I migrated from V5 to V6, where I was using WidgetModule all over the place. Would be good to know what the alternative is.

Changing it to Module instead doesn't satisfy either, since I use the override view and this isn't part of the Module class:

  Widget get view => MyWidget();

harmjanr avatar Oct 20 '23 11:10 harmjanr

Hi, alternatively you can create your own WidgetModule like this:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';

abstract class WidgetModule extends StatelessWidget implements Module {
  const WidgetModule({super.key});

  Widget get view;

  @override
  void binds(Injector i);

  @override
  List<Module> get imports => [];

  @override
  void exportedBinds(Injector i) {}

  @override
  void routes(RouteManager r) {}

  @override
  Widget build(BuildContext context) {
    return _WidgetModuleProvider(
      module: this,
      child: () => view,
    );
  }
}

class _WidgetModuleProvider<T extends Module> extends StatefulWidget {
  const _WidgetModuleProvider({super.key, required this.module, required this.child});

  final Module module;
  final Widget Function() child;

  @override
  State<_WidgetModuleProvider> createState() => _WidgetModuleProviderState();
}

class _WidgetModuleProviderState<T extends Module> extends State<_WidgetModuleProvider> {
  @override
  void initState() {
    super.initState();
    Modular.bindModule(widget.module);
    if (kDebugMode) print('-- ${widget.module.runtimeType} INITIALIZED');
  }

  @override
  void dispose() {
    Modular.unbindModule(type: widget.module.toString());
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.child();
  }
}

And use it in a similar way to version 5, but using the new Bind way from version 6:

class Counter extends ValueNotifier<int> {
  Counter() : super(0);

  increment() {
    value += 1;
  }
}

class MyWidget extends WidgetModule {
  const MyWidget({super.key});

  @override
  void binds(Injector i) {
    i.addSingleton(Counter.new);
  }

  @override
  Widget get view {
    final counter = Modular.get<Counter>();
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ValueListenableBuilder(
          valueListenable: counter,
          builder: (context, value, _) {
            return Text('Counter: ${counter.value}');
          },
        ),
        const SizedBox(width: 16),
        ElevatedButton(
          onPressed: () => counter.increment(),
          child: const Icon(Icons.add),
        ),
      ],
    );
  }
}

eduardoflorence avatar Oct 24 '23 18:10 eduardoflorence

@eduardoflorence works perfectly, thanks!

harmjanr avatar Oct 30 '23 19:10 harmjanr