获取 Dart 3 跨路由系统中集合的文档

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

Dart 3 get doc in collection across a routing system

问题

我正在尝试在我的路由系统中获取Future<>函数的返回值。

我收到了一个错误:

非空局部变量'page'在使用之前必须被赋值

由我的RouteGenerator类的返回引发。

我的RouteGenerator.dart文件:

import 'package:chope_ton_diplome/services/CommonService.dart';
import 'package:flutter/material.dart';

class RouteGenerator {
  static Route generate(RouteSettings s) {
    Widget page;
    CommonService commonService = CommonService();

    switch (s.name) {
      case RouteConsts.termsScreen:
        ArgumentsAuth args = s.arguments as ArgumentsAuth;
        commonService.terms.then((terms) =>
        page = TermsScreen(email: args.email, terms: terms)
        );
        break;
      default:
        page = const Center(
          child: Text('La route est inaccessible'),
        );
        break;
    }

    return MaterialPageRoute(builder: (context) =>
    page);
  }
}

供参考,这是我的CommonService

import 'package:cloud_firestore/cloud_firestore.dart';

class CommonService {
  final FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;

  Future<String> get terms async {
    String content = '';
    DocumentReference documentReference = firebaseFirestore.collection('commons').doc('terms');
    content = (await documentReference.get()).get('content');
    return content;
  }
}

定义一个调用我的小部件的页面,所以我被阻止了。

请帮忙。感谢您的时间。

英文:

I'm trying to get the return of a Future&lt;&gt; function across my routing system.

I got an error:

> The non-nullable local variable 'page' must be assigned before it can be used

raised by the return of my class RouteGenerator.

My RouteGenerator.dart :

import &#39;package:chope_ton_diplome/services/CommonService.dart&#39;;
import &#39;package:flutter/material.dart&#39;;

class RouteGenerator {
  static Route generate(RouteSettings s) {
    Widget page;
    CommonService commonService = CommonService();

    switch (s.name) {
      case RouteConsts.termsScreen:
        ArgumentsAuth args = s.arguments as ArgumentsAuth;
        commonService.terms.then((terms) =&gt;
        page = TermsScreen(email: args.email, terms: terms)
        );
        break;
      default:
        page = const Center(
          child: Text(&#39;La route est inaccessible&#39;),
        );
        break;
    }

    return MaterialPageRoute(builder: (context) =&gt; page);
  }
}

For information, this is my CommonService:

import &#39;package:cloud_firestore/cloud_firestore.dart&#39;;

class CommonService {
  final FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;

  Future&lt;String&gt; get terms async {
    String content = &#39;&#39;;
    DocumentReference documentReference = firebaseFirestore.collection(&#39;commons&#39;).doc(&#39;terms&#39;);
    content = (await documentReference.get()).get(&#39;content&#39;);
    return content;
  }
}

Define a page call my widget, so I'm blocked.

Help please. Thanks for your time.

答案1

得分: 2

你的generate()方法是同步的,因此它会一直执行到使用page本地变量的return语句。传递给then()的继续函数只会在generate()完成后执行。

switch语句中,在default情况下page是明确赋值的。但在其他情况下,只有当传递给then()的函数执行后(即使将来的commonService.terms已经完成),page才会被赋值。由于这不会在到达return之前发生,在这种情况下,page保持未赋值状态。

你可以通过使用基于commonService.terms未来的FutureBuilder<T>来解决这个问题。当这个未来完成时,构建器应返回预期的TermsScreen。同时,在此期间,它应该提供另一个小部件,例如CircularProgressIndicator

   case RouteConsts.termsScreen:
      ArgumentsAuth args = s.arguments as ArgumentsAuth;
      page = FutureBuilder<String>(
         future: commonService.terms,
         builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            if (snapshot.hasData) {
               return TermsScreen(email: args.email, terms: snapshot.data!);
            } else {
               return /* 一些小部件,直到条款完成 */;
            }
         }
      );
      break;
英文:

Your generate() method is synchronous so it will execute all the way down to the return statement that's using the page local variable. Continuation functions passed to then() will only execute after generate() has completed.

In the switch statement, page is definitely assigned in the default case. But not in the other case where page will only be assigned a value when the function passed to then() executes (after the future commonService.terms completes -- even if the future has completed already). Since that will not happen before return is reached, in that case, page remains unassigned.

You can work around this by assigning page with a FutureBuilder&lt;T&gt; based on the commonService.terms future. When this future complete, the builder should return the expected TermsScreen. In the meantime, it should provide another Widget, eg a CircularProgressIndicator.

   case RouteConsts.termsScreen:
      ArgumentsAuth args = s.arguments as ArgumentsAuth;
      page = FutureBuilder&lt;String&gt;(
         future: commonService.terms,
         builder: (BuildContext context, AsyncSnapshot&lt;String&gt; snapshot) {
            if (snapshot.hasData) {
               return TermsScreen(email: args.email, terms: snapshot.data!);
            } else {
               return /* some widget shown until terms completes */;
            }
         }
      );
      break;

huangapple
  • 本文由 发表于 2023年7月28日 03:32:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782881.html
匿名

发表评论

匿名网友

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

确定