Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bind(context) #30

Open
passsy opened this issue Jul 20, 2024 · 3 comments
Open

feat: bind(context) #30

passsy opened this issue Jul 20, 2024 · 3 comments

Comments

@passsy
Copy link

passsy commented Jul 20, 2024

Coming from package:provider I'm testing lite_ref and context_plus. All get the job done.

context_plus has some interesting (syntactic) features, I'd love to see in lite_ref, too.

bind

class ControlPageController extends BeaconController {
  static final ref = Ref<ControlPageController>();

  late final list = B.list<String>(['a', 'b', 'c']);
}
  @override
  Widget build(BuildContext context) {
    // bind ControlPageController to context, accessible via ControlPageController.ref for all children
    ControlPageController.ref.bind(context, () => ControlPageController());

    // directly available, without Builder()
    final controller = ControlPageController.ref.of(context);
    print(controller); // directly accessible

    return SizedBox();
  }

With lite_ref, passing anything down to the child widgets requires wrapping with LiteRefScope with overrides and a Builder to access it directly

  @override
  Widget build(BuildContext context) {
    return LiteRefScope(
      overrides: {
        // provides ControlPageController to all child widgets
        ControlPageController.ref..overrideWith((ctx) => ControlPageController()),
      },
      child: Builder(
        builder: (context) {
          // requires new context to access the controller
          final controller = ControlPageController.ref.of(context);
          print(controller);

          return SizedBox();
        }
      ),
    );
  }

The syntax it is not a dealbreaker. But it is quite verbose and adds two levels of nesting.
That I have to define overrides feels off. It might be the only time I provide a value to child widgets, not overriding anything.

Would this bind API be possible for lite_ref, too?

@yehorh
Copy link
Contributor

yehorh commented Jul 24, 2024

@passsy
Hi, may I ask why you want to use overrides? Why didn't you just declare the constructor in a static field?

import 'package:flutter/material.dart';
import 'package:state_beacon/state_beacon.dart';

void main() {
  runApp(const LiteRefScope(child: MyApp()));
}

class MyController extends BeaconController {
  static final ref = Ref.scoped((context) => MyController());
  late final list = B.list<String>(['a', 'b', 'c']);
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final controller = MyController.ref.of(context);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        body: Center(
          child: Text(
            controller.list.watch(context).toString(),
          ),
        ),
      ),
    );
  }
}

@jinyus
Copy link
Owner

jinyus commented Aug 5, 2024

I actually prefer context_ref's approach to overriding but I found that I don't use the feature much so the nesting isn't much of an issue. I'm not opposed to adding it, but I can't make any guarantees right now.

@passsy
Copy link
Author

passsy commented Aug 5, 2024

Sorry, missed your response @yehorh!

I use it in three cases: Theming, Testing and Flavouring.

For theming I created my own DefaultTextStyle for my own ui package. I override the style regularly for a part of the subtree.

For testing I inject my dependencies like an api via the context. Obviously I can't call the fake constructor from my production code where I define my objects.

I also have multiple main.dart files for different clients (flavours). I know the type of object (Auth) I inject into the widget tree, but the exact implementation depends on the client (EmailPasswordAuth, FirebaseAuth).


Again, everything is already possible. It's just the syntax that feels too verbose when I switch from a context_ref to a lite_ref project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants