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

TextFields are getting rebuild even when I use GlobalKeys. #12

Closed
cab404 opened this issue Jul 23, 2019 · 9 comments
Closed

TextFields are getting rebuild even when I use GlobalKeys. #12

cab404 opened this issue Jul 23, 2019 · 9 comments

Comments

@cab404
Copy link

cab404 commented Jul 23, 2019

To reproduce:

Program(
  view: (c,d,m) => TextField(key: GlobalKey())
  init: () => Upd(null),
  update: (msg, m) => Upd(null),
);

Each time you try to focus TextField it rebuilds and thus unfocuses. Without GlobalKey specified that is not a problem.

@cab404
Copy link
Author

cab404 commented Jul 23, 2019

upd: Also, defining global key outside view function does not work either.

dynamic view() {
  var key = GlobalKey();
  return (c,d,m) => TextField(key: key)
}
Program(
  view: view(),
  init: () => Upd(null),
  update: (msg, m) => Upd(null),
);

@p69
Copy link
Owner

p69 commented Jul 23, 2019

@cab404 Hi. Have you tried it in pure Flutter, without Dartea? It doesn't look like it's library's issue.

@cab404
Copy link
Author

cab404 commented Jul 23, 2019 via email

@cab404
Copy link
Author

cab404 commented Jul 24, 2019

@cab404 Hi. Have you tried it in pure Flutter, without Dartea? It doesn't look like it's library's issue.

Sorry, I did not include enough context (thought that I pinned down the issue).
But it only occurs if you have a Navigator in hierarchy.

Here's an example.

void main() => runApp(MaterialApp(
  routes: {
    "/": (c) => Scaffold(
      backgroundColor: Colors.amber,
      body: DarteaMessagesBus(
        child: ProgramWidget(
            withMessagesBus: true,
            init: () => Upd(1),
            view: (c, d, m) => Center(
              child: TextField(
                key: GlobalKey(),
              ),
            ),
            update: (m, s) => Upd(1)),
      ),
    )
  },
  initialRoute: "/",
));

You can remove GlobalKey(), and it would work fine, but otherwise it will close the keyboard every time text field is focused.

Sorry again for initial lack of the details :(

@p69
Copy link
Owner

p69 commented Jul 25, 2019

Sorry for the delay. I will try to reproduce and investigate this issue. Hope I can do it till next week.
Thank you for the report.

@p69
Copy link
Owner

p69 commented Jul 29, 2019

Hi @cab404 . I've reproduced this issues, and it's valid Flutter behavior. It isn't related to Dartea.

You have to define GlobalKey outside the View function, because it can be called anytime framework decides to. Focusing triggers rebuilding the tree and calling View function, and GlobalKey creates each time. You can create that key in file level, or just pass it to the main View function of the Program.

@p69 p69 closed this as completed Jul 30, 2019
@cab404
Copy link
Author

cab404 commented Aug 3, 2019

@p69 The problem is that if I use GlobalKey at file level, then there's no way to create items with it, and I see no other way to get state of a text field on button press. How should I write this?

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

var k = GlobalKey<FormFieldState<String>>();

getItem() => ProgramWidget(
      withMessagesBus: true,
      init: () => Upd(1),
      view: () {
        return (c, d, m) {
          return Column(
            children: <Widget>[
              Center(
                child: TextField(
                  key: k,
                ),
              ),
              FlatButton(
                  onPressed: () => print(k.currentState.value),
                  child: Text("Submit"))
            ],
          );
        };
      }(),
      update: (m, s) => Upd(1),
    );

void main() => runApp(MaterialApp(
      routes: {
        "/": (c) {
          return Scaffold(
            backgroundColor: Colors.amber,
            body: ListView.builder(itemBuilder: (c, i) => getItem()),
          );
        }
      },
      initialRoute: "/",
    ));

@p69
Copy link
Owner

p69 commented Aug 3, 2019

@cab404 You can use TextEditController for getting and setting text in TextField.
Alternatively you can listen text changing events and produce Messages to update your Model. As an example you can look at Search widget in Github client example. It uses stream, debounce and subscription mechanism, but in your case just updating the Model using simple dispatch inside View should be enough.

@cab404
Copy link
Author

cab404 commented Aug 3, 2019

@p69 ty, that helped :з

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

2 participants