Maison > Questions et réponses > le corps du texte
J'ai ce StatefulWidget qui est censé récupérer les données de la base de données MySQL en fonction des conditions et ajouter ces valeurs récupérées à un tableau afin que je puisse les afficher sur un ListView en utilisant les valeurs du tableau. Mon problème est que parfois lorsque le tableau (_fileValues
) 和 _custUsername
variable est vide ou n'est pas mis à jour, l'exception n'est pas levée.
Voici mon widget avec état (main.dart
)
String? _custUsername; List<String> _fileValues = <String>[]; class cakeLogin extends StatefulWidget { @override cakeLoginPageMain createState() => cakeLoginPageMain(); } class cakeLoginPageMain extends State<cakeLogin> { String? _CustEmailInit; BuildContext? loginContext; List<String> _fileNameStores = <String>[]; void callData() { // @ Get username based on user email and assign it to _custUsername variable UsernameGetter().Connection(_CustEmailInit!).then((UsernameValue) { _custUsername = UsernameValue!; }); // @ Get item names based on the user username (_custUsername) and add them into // _fileNameStores NameGetter().Connection(_custUsername).then((NamesValues) { for(var _nameItems in NamesValues) { setState(() { _fileNameStores.add(_nameItems); }); } }); // @ Remove duplicates value and add them into main list (_fileValues) var _removeDuplicates = _fileNameStores.toSet().toList(); for(var item in _removeNamesDupes) { setState(() { _fileValues.add(item); }); } } @override Widget build(BuildContext context) { final _emailController = TextEditingController(); return Scaffold( appBar: AppBar( title: Text("Login to App", style: TextStyle( fontSize: 18, color: setupFontCol, fontWeight: FontWeight.bold )), backgroundColor: setupThemeBar, centerTitle: true, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ) ), backgroundColor: setupMainTheme, body: Padding( padding: EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextFormField( controller: _emailController, style: TextStyle(color: Color.fromARGB(255, 214, 213, 213)), decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), filled: true, hintStyle: TextStyle(color: Color.fromARGB(255, 197, 197, 197)), hintText: "Enter your email", fillColor: setupThemeBar ), ), SizedBox(height: 18), SizedBox(height: 25), SizedBox( height: 45, width: 500, child: ElevatedButton( style: ElevatedButton.styleFrom( primary: setupFontCol, onPrimary: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ) ), onPressed: () { var _CustEmail = _emailController.text; if(_CustEmail.contains("@gmail.com") || _CustEmail.contains("@email.com")) { if(_CustEmail != "") { _CustEmailInit = _CustEmail; loginContext = context; _isFromLogin = true; _fileValues.clear(); callData(); } else { alertDialog("Please enter your email address",context); } } else { alertDialog("Email address is not valid",context); } }, //color: setupFontCol, child: Text("Login", style: TextStyle( color: Colors.white, fontWeight: FontWeight.normal, fontSize: 14, )) ), ), ], ), ), ); } }
UsernameGetter
Classe (Cette classe récupérera le nom d'utilisateur de la table de base de données en fonction de l'e-mail saisi dans le champ de texte)
Lorsque j'imprime la classe _usernameDetected
à partir de la classe UsernameGetter
类打印 _usernameDetected
类时,它返回返回字符串的更新版本,但是当我将 _custUsername
分配给 UsernameValue
从 main.dart
, elle renvoie une version mise à jour de la chaîne renvoyée, mais lorsque j'attribue _custUsername
à UsernameValue
de
import 'package:mysql_client/mysql_client.dart'; import 'dart:convert'; import 'dart:ffi'; import 'dart:typed_data'; import 'package:signuppage/main.dart' as main; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; class UsernameGetter { Future<String> Connection(String _custEmail) async { final conn = await MySQLConnection.createConnection( host: "", port: , userName: "", password: "", databaseName: "", ); await conn.connect(); var _getUsernameQue = await conn.execute("SELECT CUST_USERNAME FROM information WHERE CUST_EMAIL = :email", { "email": _custEmail }); String? _usernameDetected; for(final _rowsOfEmail in _getUsernameQue.rows) { _usernameDetected = _rowsOfEmail.assoc()['CUST_USERNAME']!; } return await _usernameDetected!; } }
NameGetter
classe (récupère le nom de l'élément utilisateur stocké dans la colonne de texte)
NameGetter
类,与 UsernameGetter
发生相同的情况。当我从 main.dart
检索值并将值添加到 _fileValues
Pour la classe
. Lorsque je récupère la valeur de
et que j'ajoute la valeur à la liste_fileValues
, parfois la valeur est vide et parfois la valeur n'est pas mise à jour.
import 'package:mysql_client/mysql_client.dart'; import 'dart:convert'; import 'dart:ffi'; import 'dart:typed_data'; import 'package:signuppage/main.dart' as main; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; class NameGetter { Future<List<String>> Connection(String _custUsername) async { final conn = await MySQLConnection.createConnection( host: "", port: , userName: "", password: "", databaseName: "", ); await conn.connect(); var _getItemNames= await conn.execute("SELECT ITEM_NAMES FROM item_details WHERE CUST_USERNAME = :username", { "username": _custUsername }); List<String>? _itemNamesValues= <String>[]; for(var _rowsOfItemNames in _getItemNames.rows) { var _retrieveNames = await _rowsOfItemNames.assoc()['ITEM_NAMES']!; _itemNamesValues.add(_retrieveNames); } return await _itemNamesValues; } }Je ne sais pas où sont mes erreurs, mais je suis presque sûr d'en avoir fait beaucoup et j'ai besoin de quelqu'un pour m'aider à les comprendre. Surtout en ce qui concerne la raison pour laquelle les listes et les variables ne sont pas mises à jour/parfois vides.
Lien de référence :
Flutter ListView non mis à jour
J'ai un problème avec ma liste dans Flutter qui ne met pas à jour le code🎜 🎜Pourquoi les valeurs des variables ne sont-elles pas actualisées dans Flutter ? 🎜
P粉5216974192024-04-02 09:09:07
callData()
Une version simplifiée de la méthode ressemble à ceci :
var foo; void callData() { someAsyncFunction().then( ... foo = value ... ); anotherAsyncFunction(foo).then( ... ); }
Comme mentionné précédemment, la valeur de anotherAsyncFunction(foo)
在 someAsyncFunction()
之后、then()
之前 立即调用> 分配 foo
.
Vous pouvez observer ce comportement vous-même en insérant stratégiquement des déclarations print()
.
Sous le capot, il est souvent plus facile pour les gens de déduire le comportement d'un code asynchrone lorsque Future.then()
和 async
/await
是同一件事。然而,当使用async
/await
il se lit comme du code exécuté séquentiellement.
Bien que vous puissiez utiliser n'importe lequel d'entre eux, je vous recommande de vous tourner vers async
/await
pour rendre le code plus facile à comprendre lors de la lecture.
Voici un exemple de refactorisation callData()
:
FuturecallData() async { // @ Get username based on user email and assign it to _custUsername variable var custUsername = await UsernameGetter().Connection(_CustEmailInit!); // @ Get item names based on the user username (_custUsername) and add them into // _fileNameStores var namesValues = await NameGetter().Connection(custUsername); setState(() { _fileNameStores.addAll(namesValues); // @ Remove duplicates value and add them into main list (_fileValues) _fileValues.addAll(_fileNameStores.toSet()); }); }
Écrit ainsi, il est évident que custUsername
是在调用 NameGetter().Connection(custUsername)
a été attribué auparavant.
Assurez-vous de lire Programmation asynchrone : futures, async, wait.