简体   繁体   中英

How to persist the state in flutter using bloc pattern

I have two forms Add Task and Update Task.

Both have two fields name and description. When I am trying to edit the existing task, it's not populating the values to the form.

Here's the Add Task Dialog

showDialog(
    context: context,
    builder: (context) {
      Size size = MediaQuery.of(context).size;
      return Container(
        child: AlertDialog(
          title: Text(
            'Add a new task',
            style: TextStyle(
              color: Colors.black,
              fontSize: 18.0,
            ),
          ),
          shape: RoundedRectangleBorder(
              side: BorderSide(color: primaryColor)),
          content: new Container(
            width: size.width * 0.25,
            height: size.height,
            decoration: new BoxDecoration(
              shape: BoxShape.rectangle,
              color: const Color(0xFFFFFF),
              borderRadius:
              new BorderRadius.all(new Radius.circular(32.0)),
            ),
            child: StreamBuilder(
                stream: bloc.addNewTaskStream,
                builder: (context, AsyncSnapshot<dynamic> snapshot) {
                  if (snapshot.hasData) {
                    switch (snapshot.data.status) {
                      case Status.LOADING:
                        return Loading(
                            loadingMessage: snapshot.data.message);
                        break;
                      case Status.ERROR:
                        return Error(errorMessage: snapshot.data.message);
                    }
                  }
                  return Form(
                    key: _formKey,
                    child: new Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        // dialog center
                        new Expanded(
                          child: new Column(
                            mainAxisAlignment:
                            MainAxisAlignment.center,
                            crossAxisAlignment:
                            CrossAxisAlignment.center,
                            children: <Widget>[
                              StreamBuilder<String>(
                                  stream: bloc.task,
                                  builder: (context, snapshot) {
                                    return TextFormField(
                                      decoration: InputDecoration(
                                          border: InputBorder.none,
                                          hintText: 'Name'),
                                      validator: (value) {
                                        if (value.isEmpty) {
                                          return 'Please enter the task';
                                        }
                                        return null;
                                      },
                                      onChanged: bloc.changeTask,
                                    );
                                  }),
                              StreamBuilder<String>(
                                  stream: bloc.description,
                                  builder: (context, snapshot) {
                                    return TextFormField(
                                        decoration: InputDecoration(
                                            border:
                                            InputBorder.none,
                                            hintText:
                                            'Description'),
                                        validator: (value) {
                                          if (value.isEmpty) {
                                            return 'Please enter the description';
                                          }
                                          return null;
                                        },
                                        onChanged:
                                        bloc.changeDescription);
                                  }),
                            ],
                          ),
                        ),

                        // dialog bottom
                        new Expanded(
                          child: Row(
                            mainAxisAlignment:
                            MainAxisAlignment.spaceBetween,
                            crossAxisAlignment:
                            CrossAxisAlignment.end,
                            children: <Widget>[
                              FlatButton(
                                color: Color(0XFFEFEFEF),
                                textColor: primaryColor,
                                disabledColor: Colors.grey,
                                disabledTextColor: Colors.black,
                                padding: EdgeInsets.symmetric(
                                    vertical: 15.0,
                                    horizontal: 10.0),
                                onPressed: () {
                                  Navigator.of(context).pop();
                                },
                                child: Text(
                                  "Close",
                                  style: TextStyle(
                                    fontSize: 15.0,
                                  ),
                                ),
                              ),
                              FlatButton(
                                color: primaryColor,
                                textColor: Colors.white,
                                disabledColor: Colors.grey,
                                disabledTextColor: Colors.black,
                                padding: EdgeInsets.symmetric(
                                    vertical: 15.0,
                                    horizontal: 10.0),
                                onPressed: () =>bloc.addTask(_formKey, context),
                                child: Text(
                                  "Add",
                                  style: TextStyle(
                                    fontSize: 15.0,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                }),
          ),
        ),
      );
    });

and update task form

showDialog(
    context: context,
    builder: (context) {
      Size size = MediaQuery.of(context).size;
      return Container(
        child: AlertDialog(
          title: Text(
            'Update task',
            style: TextStyle(
              color: Colors.black,
              fontSize: 18.0,
            ),
          ),
          shape: RoundedRectangleBorder(
              side: BorderSide(color: primaryColor)),
          content: new Container(
            width: size.width * 0.25,
            height: size.height,
            decoration: new BoxDecoration(
              shape: BoxShape.rectangle,
              color: const Color(0xFFFFFF),
              borderRadius:
              new BorderRadius.all(new Radius.circular(32.0)),
            ),
            child: StreamBuilder(
                stream: bloc.addNewTaskStream,
                builder: (context, AsyncSnapshot<dynamic> snapshot) {
                  if (snapshot.hasData) {
                    switch (snapshot.data.status) {
                      case Status.LOADING:
                        return Loading(
                            loadingMessage: snapshot.data.message);
                        break;
                      case Status.ERROR:
                        return Error(errorMessage: snapshot.data.message);
                    }
                  }
                  return Form(
                    key: _formKey,
                    child: new Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        // dialog center
                        new Expanded(
                          child: new Column(
                            mainAxisAlignment:
                            MainAxisAlignment.center,
                            crossAxisAlignment:
                            CrossAxisAlignment.center,
                            children: <Widget>[
                              StreamBuilder<String>(
                                  stream: bloc.task,
                                  builder: (context, snapshot) {
                                    return TextFormField(
                                      decoration: InputDecoration(
                                          border: InputBorder.none,
                                          hintText: 'Name'),
                                      validator: (value) {
                                        if (value.isEmpty) {
                                          return 'Please enter the task';
                                        }
                                        return null;
                                      },
                                      onChanged: bloc.changeTask,
                                    );
                                  }),
                              StreamBuilder<String>(
                                  stream: bloc.description,
                                  builder: (context, snapshot) {
                                    return TextFormField(
                                        decoration: InputDecoration(
                                            border:
                                            InputBorder.none,
                                            hintText:
                                            'Description'),
                                        validator: (value) {
                                          if (value.isEmpty) {
                                            return 'Please enter the description';
                                          }
                                          return null;
                                        },
                                        onChanged:
                                        bloc.changeDescription);
                                  }),
                            ],
                          ),
                        ),

                        // dialog bottom
                        new Expanded(
                          child: Row(
                            mainAxisAlignment:
                            MainAxisAlignment.spaceBetween,
                            crossAxisAlignment:
                            CrossAxisAlignment.end,
                            children: <Widget>[
                              FlatButton(
                                color: Color(0XFFEFEFEF),
                                textColor: primaryColor,
                                disabledColor: Colors.grey,
                                disabledTextColor: Colors.black,
                                padding: EdgeInsets.symmetric(
                                    vertical: 15.0,
                                    horizontal: 10.0),
                                onPressed: () {
                                  Navigator.of(context).pop();
                                },
                                child: Text(
                                  "Close",
                                  style: TextStyle(
                                    fontSize: 15.0,
                                  ),
                                ),
                              ),
                              FlatButton(
                                color: primaryColor,
                                textColor: Colors.white,
                                disabledColor: Colors.grey,
                                disabledTextColor: Colors.black,
                                padding: EdgeInsets.symmetric(
                                    vertical: 15.0,
                                    horizontal: 10.0),
                                onPressed: () =>bloc.updateTask(_formKey, context, selectedTaskId),
                                child: Text(
                                  "Update",
                                  style: TextStyle(
                                    fontSize: 15.0,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                }),
          ),
        ),
      );
    });

On click of editTask, I am adding the values to sink.

    class TimesheetBloc{
  TimesheetRepository _timesheetRepository = new TimesheetRepository();

  //declare streams
  final _addNewTask = BehaviorSubject<Response<String>>();
  final _description = BehaviorSubject<String>();
  final _task = BehaviorSubject<String>();
  final _hours = BehaviorSubject<double>();

  //get data from streams
  Stream<Response<String>> get addNewTaskStream => _addNewTask.stream;
  Stream<String> get description => _description.stream;
  Stream<String> get task => _task.stream;

  //set data
  StreamSink<Response<String>> get addNewTaskSink => _addNewTask.sink;
  Function(String) get changeDescription => _description.sink.add;
  Function(String) get changeTask => _task.sink.add;

  //dispose
  dispose(){
    _description.close();
    _hours.close();
    _addNewTask.close();
    _task.close();
  }
  
  addTask(_formKey, context, DateTime date)async {
    if (_formKey.currentState.validate()) {
      final description =  _description.value;
      final task =  _task.value;
      addNewTaskSink.add(Response.loading('Please wait'));
          var data = await _timesheetRepository.addNewTask(task, description);
          Map<String, dynamic> message = Map.castFrom(data);
          addNewTaskSink.add(Response.completed(message['message']));
        Navigator.of(context).pop();
    }
  }
  editTask (context, taskObject) async {
    String description = taskObject['description'];
    String taskName = taskObject['taskName'];
    _task.sink.add(taskName);
    _description.sink.add(description);
  }

  updateTask (_formKey, context, uuid) async {
    if (_formKey.currentState.validate()) {
      final description =  _description.value;
      final task =  _task.value;

      addNewTaskSink.add(Response.loading('Please wait'));
        var data = await _timesheetRepository.updateTask(uuid, task, description);
        Map<String, dynamic> message = Map.castFrom(data);
        addNewTaskSink.add(Response.completed(message['message']));
        Navigator.of(context).pop();
    }
  }
}

Here are the AddTAsk and UpdateTask form

添加任务

更新任务

The Best way is to use bloc library it contains BloCProvider.value and Give you more control over your context and data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM