【问题标题】:How to persist the state in flutter using bloc pattern如何使用 bloc 模式在颤动中保持状态
【发布时间】:2021-04-19 18:37:20
【问题描述】:

我有两个表单添加任务和更新任务。

两者都有两个字段名称和描述。当我尝试编辑现有任务时,它不会将值填充到表单中。

这是添加任务对话框

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,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                }),
          ),
        ),
      );
    });

并更新任务表单

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,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                }),
          ),
        ),
      );
    });

点击editTask,我将值添加到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();
    }
  }
}

这里是 AddTAsk 和 UpdateTask 表单

【问题讨论】:

    标签: flutter dart flutter-layout flutter-dependencies flutter-web


    【解决方案1】:

    最好的方法是使用它包含的 bloc 库 BloCProvider.value 并让您更好地控制您的上下文和数据

    【讨论】:

    • 我只在有单独的 Provider 和 Bloc 类的情况下使用 BLOC 模式。你能否解释一下我能做些什么改变。正如您在 bloc 文件中看到的 editTask 函数,我已经在向 sink 添加值。
    猜你喜欢
    • 2020-08-01
    • 2023-01-17
    • 2021-08-14
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2018-12-19
    • 2020-01-31
    相关资源
    最近更新 更多