Flutter go_router: push() vs go() and web URL changes

huangapple go评论62阅读模式
英文:

Flutter go_router: push() vs go() and web URL changes

问题

以下是您要翻译的内容:

"I am facing a use case I don't know the proper way to deal with.

Please see here the simple application I have made: https://dartpad.dev/?id=5a00b315613990d8c3ead6e26bc2df4c

This tries to simulate the typical scenario where you have a record list page with data recovered from a data base, click on one of the records, make some changes and click the "Save" button to go back to the list page and see those changes updated.

If I use context.push(), I can see the changes correctly because it returns a Future so I can wait until context.pop() is executed in the detail screen and then I run getDataFromDataBase() to refresh the data from the database.

The problem I have with using context.push() is the URL is not updated when I run this for the web.

If I use context.go() instead then the URL is properly updated but since this returns void I cannot properly wait to update the records after context.pop()

I feel I am missing something because this must be a very typical scenario. Let's see if you can point me in the right direction:

  1. Is it the expected behaviour that context.push() doesn't modify the URL?
  2. In case I use context.go() instead (which by the way seems to be the recommended way to navigate according to the official documentation since imperative navigation can cause some problems: https://pub.dev/documentation/go_router/latest/topics/Navigation-topic.html). What's the proper way to manage this scenario? How to update data after context.pop()

Thank you."

英文:

I am facing a use case I don't know the proper way to deal with.

Please see here the simple application I have made: https://dartpad.dev/?id=5a00b315613990d8c3ead6e26bc2df4c

This tries to simulate the typical scenario where you have a record list page with data recovered from a data base, click on one of the records, make some changes and click the "Save" button to go back to the list page and see those changes updated.

If I use context.push(), I can see the changes correctly because it returns a Future so I can wait until context.pop() is executed in the detail screen and then I run getDataFromDataBase() to refresh the data from the database.

The problem I have with using context.push() is the URL is not updated when I run this for the web.

If I use context.go() instead then the URL is properly updated but since this returns void I cannot properly wait to update the records after context.pop()

I feel I am missing something because this must be a very typical scenario. Let's see if you can point me in the right direction:

  1. Is it the expected behaviour that context.push() doesn't modify the URL?
  2. In case I use context.go() instead (which by the way seems to be the recommended way to navigate according to the official documentation since imperative navigation can cause some problems: https://pub.dev/documentation/go_router/latest/topics/Navigation-topic.html). What's the proper way to manage this scenario? How to update data after context.pop()

Thank you.

答案1

得分: 1

目前,我正在寻找答案来回答你的第一个问题,所以我无法回答。

至于第二个问题,你可以通过创建一个 Promise,并将完成该 Promise 的函数传递给你的编辑对话框来解决它。

类似这样的方式:

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

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      // ...
      TextButton(
        onPressed: () async {
          final promise = Completer<bool>();
          context.go('/somePath', extra: promise.complete);
          final editResult = await promise.future;
          // ....
        },
        child: Text('Edit'),
      )
    ]);
  }
}

然后,你可以从路由的 extra 字段中获取这个函数,将它传递给你的对话框,并在编辑完成后调用它。

英文:

ATM, I'm looking for an answer to your first question myself so I can't answer that.

As for the second one, you can work around it by creating a Promise, and pass a function fulfilling that promise into your editing dialog.

Something like this:

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

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      // ...
      TextButton(
        onPressed: () async {
          final promise = Completer&lt;bool&gt;();
          context.go(&#39;/somePath&#39;, extra: promise.complete);
          final editResult = await promise.future;
          // ....
        },
        child: Text(&#39;Edit&#39;),
      )
    ]);
  }
}

You can then pick the function up from the extra-field in your route, pass it into your dialog and call it when editing is done.

huangapple
  • 本文由 发表于 2023年7月20日 22:26:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76730901.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定