Как преобразовать снимок потока BLoC флаттера в пользовательский объект?

Я пытаюсь реализовать шаблон BLoC в своем приложении флаттера, в основном это приложение вычисляет какой-то результат и отображает его в таблице. я создал CalculationResultProvider и CalculationResultBloc следующим образом

class CalculationResultProvider 
{   
List<EstimationResult> resultList = new List();

  List<EstimationResult> calculateResult(){
    return getInitialData();   }

  List<EstimationResult> getInitialData(){
        var cement = new EstimationResult();
        cement.material = "Cement";
        cement.unit = "Ton";
        cement.qty = 10;

        var sand = new EstimationResult();
        sand.material = "Sand";
        sand.unit = "Ton";
        sand.qty = 12;

        var gravel = new EstimationResult();
        gravel.material = "Gravel";
        gravel.unit = "Ton";
        gravel.qty = 5;

        var steel = new EstimationResult();
        steel.material = "Steel";
        steel.unit = "Ton";
        steel.qty = 5;

        List<EstimationResult> resultList = new List();
        resultList.add(cement);
        resultList.add(sand);
        resultList.add(gravel);
        resultList.add(steel);

        return resultList;    }  }

и мой класс поставщика BLoC следующим образом

class CalculationResultBloc {
  final resultController = StreamController(); // create a StreamController
  final CalculationResultProvider provider =
      CalculationResultProvider(); // create an instance of our CounterProvider

  Stream get getReult =>
      resultController.stream; // create a getter for our stream

  void updateResult() {
    provider
        .calculateResult(); // call the method to increase our count in the provider
    resultController.sink.add(provider.resultList); // add the count to our sink
  }

  void dispose() {
    resultController.close(); // close our StreamController
  }
}

тогда мне нужно показать эти данные в виджете таблицы

class ResultTableWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => ResultTableWidgetState();
}

class ResultTableWidgetState extends State {
  final bloc =
      CalculationResultBloc(); // create an instance of the counter bloc

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: bloc.getReult,
        initialData: CalculationResultProvider().getInitialData(),
        builder: (context, snapshot) {
          DataTable(
            columns: [
              DataColumn(label: Text('Patch')),
              DataColumn(label: Text('Version')),
              DataColumn(label: Text('Ready')),
            ],
            rows:
                '${snapshot.data}' // Loops through dataColumnText, each iteration assigning the value to element
                    .map(
                      ((element) => DataRow(
                            cells: <DataCell>[
                              DataCell(Text(element[
                                  "Name"])), //Extracting from Map element the value
                              DataCell(Text(element["Number"])),
                              DataCell(Text(element["State"])),
                            ],
                          )),
                    )
                    .toList(),
          );
        });
  }

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }
}

Для итерации возвращаемой таблицы это должно быть List<EstimationResult>

а как превратить снапшот в List<EstimationResult>?

где лучше всего трансформироваться внутри класса блока или в классе виджетов?

Я новичок в дротике и флаттере, может ли кто-нибудь ответить на мои вопросы?

Благодарю.


person Roshan    schedule 30.04.2019    source источник


Ответы (1)


Ваш класс виджета не будет иметь представления о типе данных, заданном функцией потока в вашем StreamBuilder, есть много способов преобразовать данные в BloC прямо перед потоковой передачей, но все они будут бесполезны, потому что для класса виджета это всего лишь snapshot , и единственные поля, к которым вы можете получить доступ во время компиляции, - это те, которые применяются к универсальному снимку, например поле data. Итак, единственный способ получить доступ к настраиваемым полям списка - указать вашему StreamBuilder, какой тип данных следует ожидать от его функции stream:

  StreamBuilder<List<EstimationResult>>(
    stream: bloc.getReult,
    initialData: CalculationResultProvider().getInitialData(),
    builder: (context, snapshot) {
     //...
    }
  );

Таким образом, вы можете рассматривать свой snapshot как List<EstimationResult> и иметь доступ к внутренним полям и функциям прямо перед тем, как вы получите фактический снимок. В вашем случае, вероятно, вам следует импортировать класс EstimationResult в свой класс виджета.

person Mazin Ibrahim    schedule 01.05.2019
comment
Спасибо, есть ли какие-нибудь лучшие практики для достижения моей цели? - person Roshan; 01.05.2019
comment
Что ж, я мало знаю о DataTable, возможно, чтение о том, как их заполнять, даст вам представление. - person Mazin Ibrahim; 01.05.2019
comment
Я реализовал ваше решение, но дело в том, как преобразовать snapshot.data в список, простите меня, если я снова и снова спрашиваю одно и то же, - person Roshan; 01.05.2019