局部变量和全局变量的颤振Riverpod [英] Flutter Riverpod for local and global variables

查看:12
本文介绍了局部变量和全局变量的颤振Riverpod的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个文本编辑控制器,我试图为这些文本编辑控制器提供从API获取的初始值。我需要全局声明文本编辑控制器并从API中给出初始值,所以我需要对全局变量使用data3.firstName和data3.lastName,如果我尝试声明变量和Build中的函数,它不起作用,所以只需要将获取的数据用于全局文本编辑控制器,这样我就可以给出初始值。

late Future<Response> futureData;

  @override
  void initState() {
    super.initState();
    futureData = fetchAccountData();
  }

  final _formKey = GlobalKey<FormState>();

  TextEditingController editedFirstName =
      TextEditingController(text: 'Hello'); // needs to be data3.firsName
  TextEditingController editedLastName = TextEditingController(text: 'Riverpod looks great');// needs to be data3.lastName

  Future<void> putAccountData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? authorization = prefs.getString('authorization');
    var url = 'https://dev.api.wurk.skyver.co/api/v1/employees/account';
    Map payload = {
      "firstName": editedFirstName.text,
      "lastName": editedLastName.text,
    };
    try {
      final response = await http.put(Uri.parse(url),
          headers: <String, String>{
            'authorization': authorization ?? basicAuth.toString(),
            "Content-Type": "application/json"
          },
          body: jsonEncode(payload));
    } catch (er) {}
  }

  @override
  Widget build(BuildContext context) {
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;

    return SafeArea(
      child: WillPopScope(
        onWillPop: () async {
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(
              builder: (context) => const ProfileScreen(),
            ),
          );
          return shouldPop;
        },
        child: KeyboardDismisser(
          gestures: const [
            GestureType.onTap,
            GestureType.onPanUpdateDownDirection
          ],
          child: Form(
            key: _formKey,
            child: Scaffold(
                resizeToAvoidBottomInset: false,
                appBar: AppBar(
                  backgroundColor: Colors.blue,
                  title: const Text(
                    'Edit My Profile',
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                  leading: IconButton(
                    icon: const Icon(Icons.arrow_back),
                    onPressed: () {
                      Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder: (context) => const ProfileScreen(),
                        ),
                      );
                    },
                  ),
                ),
                body: FutureBuilder<Response>(
                  future: futureData,
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      AccountData data3 = AccountData.fromJson(
                        json.decode(snapshot.data!.body),
                      );

                      return Column(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          Container(
                            width: width,
                            height: height / 1.9,
                            decoration: BoxDecoration(
                              border: Border.all(
                                color: Colors.black,
                                width: 3,
                              ),
                            ),
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                              children: [
                                Row(
                                  children: [
                                    const Padding(
                                      padding: EdgeInsets.all(30),
                                      child: Text(
                                        "First Name:",
                                        style: TextStyle(
                                            fontSize: 20,
                                            fontWeight: FontWeight.bold),
                                      ),
                                    ),
                                    const Spacer(),
                                    Padding(
                                      padding: const EdgeInsets.all(30),
                                      child: SizedBox(
                                        width: width / 2.5,
                                        child: Center(
                                          child: TextFormField(
                                            textAlignVertical:
                                                TextAlignVertical.center,
                                            //initialValue: editedFirstName.text = data3.firstName,
                                            controller: editedFirstName,
                                            // ..selection =
                                            //     TextSelection.collapsed(
                                            //         offset: data3
                                            //             .firstName.length),
                                            decoration: InputDecoration(
                                              contentPadding:
                                                  const EdgeInsets.symmetric(
                                                      vertical: 10.0,
                                                      horizontal: 10.0),
                                              border: OutlineInputBorder(
                                                borderRadius:
                                                    BorderRadius.circular(10),
                                                borderSide: const BorderSide(
                                                    color: Colors.red,
                                                    width: 1),
                                              ),
                                            ),
                                            style: const TextStyle(
                                              fontSize: 17,
                                              fontWeight: FontWeight.bold,
                                            ),
                                            // inputFormatters: [
                                            //   LengthLimitingTextInputFormatter(15)
                                            // ],
                                            validator: (value) {
                                              if (value == null ||
                                                  value.isEmpty) {
                                                return 'Name is required';
                                              }
                                              return null;
                                            },
                                          ),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                                Row(
                                  children: [
                                    const Padding(
                                      padding: EdgeInsets.all(30),
                                      child: Text(
                                        'Last Name:',
                                        style: TextStyle(
                                          fontSize: 20,
                                          fontWeight: FontWeight.bold,
                                        ),
                                      ),
                                    ),
                                    const Spacer(),
                                    Padding(
                                      padding: const EdgeInsets.all(30),
                                      child: SizedBox(
                                        width: width / 2.5,
                                        child: TextFormField(
                                          //initialValue: editedLastName.text = data3.lastName,
                                          controller: editedLastName,
                                          // ..selection =
                                          //     TextSelection.collapsed(
                                          //         offset:
                                          //             data3.lastName.length),
                                          decoration: InputDecoration(
                                            contentPadding:
                                                const EdgeInsets.symmetric(
                                                    vertical: 10.0,
                                                    horizontal: 10.0),
                                            border: OutlineInputBorder(
                                              borderRadius:
                                                  BorderRadius.circular(10),
                                            ),
                                          ),
                                          style: const TextStyle(
                                              fontSize: 17,
                                              fontWeight: FontWeight.bold),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),

推荐答案

看起来您想要为TextField提供初始值,但该值是从服务器异步获取的。

您使用TextEditingController是正确的,但是因为您一开始没有准备好值,所以在创建控制器时不应该使用TextEditingController(text: 'Hello')

相反,您可以创建一个没有默认值的控制器,例如:final _controller = TextEditingController()。然后在得到数据后,比如说在initState中调用fetchAccountData()方法后,可以使用_controller.text = fetchedValue将数据分配给控制器。

我看到您也在使用FutureBuilder。根据您希望在加载";默认值";之前显示的内容,您可能不再需要FutureBuilder

快速演示:

class QuickDemo extends StatefulWidget {
  const QuickDemo({Key? key}) : super(key: key);

  @override
  _QuickDemoState createState() => _QuickDemoState();
}

class _QuickDemoState extends State<QuickDemo> {
  final _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  _fetchData() async {
    // do your network call here
    await Future.delayed(const Duration(seconds: 1));
    // and then parse your response here
    final data = 'Hello';
    // eventually you will have data, so assign it:
    _controller.text = data;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField(
          controller: _controller,
        ),
      ),
    );
  }
}

这篇关于局部变量和全局变量的颤振Riverpod的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆