在Flutter中从数据库加载一些数据的正确方法是什么?

bzzcjhmw  于 2023-05-19  发布在  Flutter
关注(0)|答案(3)|浏览(264)

考虑到我们有一个类似于以下的函数,从数据库加载数据:

loadData() async {
    loadedData = await loadingData();
    return loadedData;
  }

我们希望在使用Provider包的相同或其他类/小部件中使用此loadedData
我尝试了很多方法,比如将loadData()放在initState()didChangeDependencies()中,如下所示:

@override
  void didChangeDependencies() async {
    super.didChangeDependencies();
    data = await Provider.of<>(context , listen: false).loadData();
  }

或者使用Consumer或尝试在应用程序启动时使用ChangeNotifierProxyProvider传递数据,但大多数时候仍然有问题,并得到错误,如null值错误或一些其他相关错误(目前不记得了)。

我想知道从数据库中获取数据并等待Widget中的数据的正确方法是什么?

例如,我知道如果我在Provider命令中将(listen: false)更改为(listen: true),我可以读取数据,但似乎它更新了应用程序很多,我可以听到CPU风扇的噪音,我不喜欢它!
请给予我一个简单的代码示例/片段,以了解正确的方式做到这一点?

7fhtutme

7fhtutme1#

您可以使用FutureBuilder加载数据,如下所示:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: Provider.of<MyData>(context, listen: false).loadData(),
      builder: (BuildContext context, AsyncSnapshot<MyData> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: CircularProgressIndicator(),
          );
        } else if (snapshot.hasError) {
          return Center(
            child: Text('Error: ${snapshot.error}'),
          );
        } else {
          MyData data = snapshot.data!;
          // Use the loaded data to build your widget
          return Text(data.someProperty);
        }
      },
    );
  }
}
j91ykkif

j91ykkif2#

下面是一个使用提供程序的loadData示例。如果不想立即加载数据,只需删除initState()方法。

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
    void initState() {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        context.read<TestModel>().loadData();
      });
      super.initState();
    }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _buildContent()
    );
  }

  Widget _buildContent() {
    ///context.watch only rebuild when [TestModel] changes.
    TestModel testModel = context.watch<TestModel>();
    if (testModel.isLoading) {
        return Center(child: CircularProgressIndicator());
      } else {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(testModel.data),
              ElevatedButton(
                onPressed: () async => await testModel.loadData(),
                child: Text('Click to Load Data'),
              ),
            ],
          ),
        );
      }
    }
  }

class TestModel with ChangeNotifier {
  String _data = '';
  bool _isLoading = false;

  String get data => _data;
  bool get isLoading => _isLoading;

  Future<void> loadData() async {
    _isLoading = true;
    notifyListeners();
    // your logic here
    await Future.delayed(Duration(seconds: 2));
    _data = 'Finish loading data with result';
    _isLoading = false;
    notifyListeners();
  }
}
vkc1a9a2

vkc1a9a23#

您可以使用FutureBuilder或通过使用车削操作员。

data == null || data.isEmpty
? CircularProgressIndicator() 
: Center(
    child: Text("It is working")
),

相关问题