Flutter State Management: использование `Provider` - PullRequest
1 голос
/ 28 февраля 2020

Я на первых экранах разработки моего приложения для флаттера, в настоящее время использую setState для управления состоянием . Ну, мне нужно отойти от этого и использовать provider вместо этого.

Ниже приведен пример кода для экрана my account, где пользователи могут изменять информацию своего профиля. Ниже описано, что он делает.

  1. Загрузка пользовательских данных в init
  2. Обновление пользовательских данных при нажатии кнопки

Я думаю о том, как лучше управлять state, потому что мне нужно отобразить сообщение ожидания при сохранении данных и сообщение об успешном сохранении при сохранении данных. Я уже использую Загрузка данных Сообщение при init Загрузка данных.

Ниже мой код

AccountPage

    import 'package:flutter/material.dart';
import 'package:xxx/models/company.dart';
import 'package:xxx/models/user.dart';
import 'package:xxx/services/user/user_impl.dart';
import 'package:xxx/services/user/user_interface.dart';

class AccTest extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My App"),
      ),
      body: AccTestForm(),
    );
  }
}

class AccTestForm extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return AccTestState();
  }
}

class AccTestState extends State<AccTestForm> {
  final _formKey = GlobalKey<FormState>();

  TextEditingController nameController = TextEditingController();

  UserInterface userinterface = UserImpl();

  int userID = 0;
  int companyID = 0;

  @override
  Widget build(BuildContext context) {
    /**
     * here i am checking for `userID` which was set via `setState`
     */
    if (userID > 0) {
      return ListView(
        children: <Widget>[
          Container(
            child: Text(
              "This is your account section. You can update and change information as you prefer.",
              style: Theme.of(context).textTheme.subhead,
            ),
            margin: EdgeInsets.only(left: 10, right: 10, top: 30),
          ),
          Container(
            child: FutureBuilder(
              future: userinterface.getUserWithCompanyInfo(userID),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.connectionState == ConnectionState.done &&
                    snapshot != null) {
                  nameController.text = snapshot.data.name;

                  companyID = snapshot.data.company.idcompany;

                  print("BUILD FORM PRINTED");

                  return _buildForm();
                } else {
                  return Center(
                    child: Container(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          CircularProgressIndicator(),
                          Container(
                            height: 10,
                          ),
                          Text(
                            "Loading Data... Please Wait",
                            style: Theme.of(context).textTheme.body1,
                          )
                        ],
                      ),
                    ),
                  );
                }
              },
            ),
            margin: EdgeInsets.only(left: 10, right: 10, top: 30),
          )
        ],
      );
    } else {
      return Center(
        child: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              CircularProgressIndicator(),
              Container(
                height: 10,
              ),
              Text(
                "Loading Data... Please Wait",
                style: Theme.of(context).textTheme.body1,
              )
            ],
          ),
        ),
      );
    }
  }

  Widget _buildForm() {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
              margin: EdgeInsets.only(left: 8, bottom: 5),
              child: Text(
                "Name",
                style: Theme.of(context).textTheme.subtitle,
              )),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                  child: TextFormField(
                  controller: nameController,
                  keyboardType: TextInputType.text,
                ),)
            ],
          ),
          Container(
            margin: EdgeInsets.only(top: 40, left: 20, right: 20, bottom: 20),
            child: RaisedButton(
                    color: Color.fromRGBO(0, 72, 128, 100),
                    textColor: Colors.white,
                    child: Text(
                      "Save Information",
                      style: Theme.of(context).textTheme.button,
                    ),
                    onPressed: () {
                      if (_formKey.currentState.validate()) {

                        String saveState = null;

                        /**
                         * Updating the `user`
                         */
                        Company company = Company(idcompany: companyID);

                        User user = User(
                          iduser: userID,
                          name: nameController.text,
                          company: company,
                          phone: "something",
                          email: "test@test.com",
                          companyDesignation: "something",
                        );

                        UserInterface userInterface = UserImpl();


                        userInterface.updateUser(user).then((val) {
                          print("User Update: " + val);

                           Scaffold.of(context).showSnackBar(
                              SnackBar(content: Text("ssdsd")));


                        });
                      }
                    },
                  ),
          )
        ],
      ),
    );
  }

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

  /**
   * Here i get user information by email, then assign them to `userID` global variable
   */
    userinterface.getUserByEmail("test@test.com").then((val) {
      setState(() {
        userID = val.iduser;
      });

      print("user id: " + val.iduser.toString());
    });
  }
}

UserImpl

import 'package:flutter/material.dart';
import 'package:xxx/models/user.dart';
import 'package:xxx/services/nav_links.dart';
import 'package:xxx/services/user/user_interface.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as convert;

class UserImpl implements UserInterface 
{
  NavLinks navLinks = NavLinks();

  /**
   * Get user with company information
   */
  @override
  Future <User> getUserWithCompanyInfo(int userID) async {
    var data = await http.get(navLinks.getUserWithCompanyInfo(userID));

    if (data.statusCode == 200) {
      return User.fromJson(convert.json.decode(data.body));
    } else {
      throw Exception('Failed to load post');
    }
  }

  @override
  Future<User> getUserByEmail(String email)  async{
    var data = await http.get(navLinks.getUserByEmail(email));

    if (data.statusCode == 200) {
      return User.fromJson(convert.json.decode(data.body));
    } else {
      throw Exception('Failed to load post');
    }
  }

  Future<String> updateUser(User body) async {
    print("BODY: " + body.toJson().toString());

    return http.post(navLinks.updateUser(), body: convert.json.encode(body.toJson()), headers: {
      "Accept": "application/json",
      "content-type": "application/json"
    }).then((http.Response response) {
      final int statusCode = response.statusCode;

      print("RESPONSE: " + response.body);
      print("STATUS CODE: " + statusCode.toString());

      if (statusCode < 200 || statusCode > 400 || response.body == null) {
        throw new Exception("Error while fetching data");
      } else {
        return response.body;
      }
    });
  }

}

Я очень растерялся, пытаясь применить provider к этому, потому что мне приходится иметь дело с парой Future и ее возвращающими данными.

Любая поддержка по преобразованию этого в provider, пожалуйста?

...