Flutter tidak boleh mendapatkan nilai baharu pembolehubah apabila dipanggil dalam kelas lain
P粉670107661
P粉670107661 2024-04-01 22:37:38
0
1
463

Saya mempunyai StatefulWidget ini yang sepatutnya mengambil data daripada pangkalan data MySQL berdasarkan syarat dan menambah nilai yang diambil ini pada tatasusunan supaya saya boleh memaparkan pada ListView menggunakan nilai tatasusunan. Masalah saya ialah kadangkala apabila tatasusunan (_fileValues) 和 _custUsername pembolehubah kosong atau tidak dikemas kini, pengecualian tidak dibuang.

Ini adalah widget stateful saya (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 Kelas (Kelas ini akan mendapatkan nama pengguna pengguna dari jadual pangkalan data berdasarkan e-mel dalam input medan teks)

Apabila saya mencetak kelas _usernameDetected daripada kelas UsernameGetter 类打印 _usernameDetected 类时,它返回返回字符串的更新版本,但是当我将 _custUsername 分配给 UsernameValuemain.dart ia mengembalikan versi kemas kini bagi rentetan yang dikembalikan, tetapi apabila saya menetapkan _custUsername kepada UsernameValue daripada

, ia tidak mengemas kini dan kadangkala mengembalikan nilai nol.

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

kelas (dapatkan semula nama item pengguna yang disimpan dalam lajur teks)

NameGetter 类,与 UsernameGetter 发生相同的情况。当我从 main.dart 检索值并将值添加到 _fileValuesUntuk kelas

, perkara yang sama berlaku dengan

. Apabila saya mendapatkan semula nilai daripada

dan menambah nilai pada senarai _fileValues, kadangkala nilai itu kosong dan kadangkala nilai itu tidak dikemas kini.

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;
  }
}

Saya tidak pasti di mana kesilapan saya, tetapi saya pasti saya telah melakukan banyak kesilapan dan saya memerlukan seseorang untuk membantu saya memikirkannya. Terutama mengenai sebab senarai dan pembolehubah tidak dikemas kini/kadang-kadang kosong.

Pautan rujukan:

Flutter ListView tidak dikemas kini

Saya menghadapi masalah dengan senarai saya dalam flutter tidak mengemas kini kod🎜 🎜Mengapa nilai pembolehubah tidak dimuatkan semula secara berkibar? 🎜
P粉670107661
P粉670107661

membalas semua(1)
P粉521697419

Soalan

callData() Versi ringkas kaedah kelihatan seperti ini:

  var foo;

  void callData() {
    someAsyncFunction().then( ... foo = value ... );
    anotherAsyncFunction(foo).then( ... );
  }

Seperti yang dinyatakan sebelum ini, nilai anotherAsyncFunction(foo)someAsyncFunction() 之后、then() 之前 立即调用> 分配 foo.

Anda boleh memerhati tingkah laku ini sendiri dengan memasukkan print() kenyataan secara strategik.

Penyelesaian

Di bawah hud, selalunya lebih mudah untuk orang membuat kesimpulan tentang kelakuan kod tak segerak apabila Future.then()async/await 是同一件事。然而,当使用async/await ia berbunyi seperti kod yang dilaksanakan secara berurutan.

Walaupun anda boleh menggunakan mana-mana daripadanya, saya syorkan beralih kepada async/await untuk menjadikan kod lebih mudah difahami semasa membaca.

Berikut adalah contoh cara memfaktorkan semula callData():

  Future callData() 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());
    });
  }

Ditulis begini, nampaknya custUsername 是在调用 NameGetter().Connection(custUsername) telah ditugaskan sebelum ini.

Pastikan membaca Pengaturcaraan tak segerak: niaga hadapan, tak segerak, menanti.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan