【问题标题】:How to add data to a list inside a class model from firebase. Flutter如何从 firebase 将数据添加到类模型内的列表中。扑
【发布时间】:2021-02-04 00:49:50
【问题描述】:

我有一个包含列表的类模型“存储库”。 此列表包含一些数据..like this..

import 'state_model.dart';

class Repository {
  dynamic getAll() => _india.length;

  getLocalByState(String state) => _india
      .map((map) => StateModel.fromJson(map))
      .where((item) => item.state == state)
      .map((item) => item.lgas)
      .expand((i) => i)
      .toList();

  List<String> getStates() => _india
      .map((map) => StateModel.fromJson(map))
      .map((item) => item.state)
      .toList();

  List<Map> _india= [
    {
      "state": "Kerala",
      "alias": "adamawa",
      "lgas": [
        "Kannur",
        "Kochi",
        "Kasargode",
      ]
    },
    {
      "state": "Karanataka",
      "alias": "akwa_ibom",
      "lgas": ["Banglore", "Mysore", "HasanNagar"]
    },
    {
      "state": "Tamil Nadu",
      "alias": "ogun",
      "lgas": [
        "Chennai",
        "Vellore",
        "Coimbatore",
        "Selam",
      ]
    },
  ];
}

我想要的是从 firebase 数据中添加数据。其中包含与上述列表中相同的 JSON 数据。 使用上述数据,我创建了一个自定义下拉按钮。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:grocbstoremanager/repository.dart';

class CustomDropDown extends StatefulWidget {
  final Function func1;
  final Function func2;
  final String item;
  final bool edit;
  final String item2;

  const CustomDropDown(
      {this.func1, this.func2, this.item, this.edit, this.item2});

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

class _CustomDropDownState extends State<CustomDropDown> {
  List<String> _states = ["Choose Category"];
  List<String> _lgas = ["Choose .."];
  String _selectedState = "Choose Category";
  String _selectedLGA = "Choose ..";

  Repository repo = Repository();
  
  void getdata() {
    Firestore.instance.collection("Categories").getDocuments().then((value) {
      print(value.documents.last.data);
      _states.add(value.documents.last.data["state"]);
      print((value.documents.last.data["lgas"]));
      _lgas.add((value.documents.last.data["lgas"][0]));
    });
    print("added data wow...");
  }

  @override
  void initState() {
    getdata();
    
    _states = List.from(_states)..addAll(repo.getStates());
    super.initState();
  }

  void _onSelectedState(String value) {
    setState(() {
      _selectedLGA = "Choose ..";
      _lgas = ["Choose .."];
      _selectedState = value;
      _lgas = List.from(_lgas)..addAll(repo.getLocalByState(value));
      widget.func1(_selectedState);
    });
  }

  void _onSelectedLGA(String value) {
    setState(() {
      _selectedLGA = value;
      widget.func2(_selectedLGA);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 49,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Flexible(
            flex: 3,
            child: FormField(builder: (FormFieldState<String> state) {
              return InputDecorator(
                decoration: InputDecoration(
                    contentPadding: EdgeInsets.only(left: 10, right: 10),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0))),
                child: DropdownButtonHideUnderline(
                  child: DropdownButton<String>(
                    isExpanded: true,
                    items: _states.map((String dropDownStringItem) {
                      return DropdownMenuItem<String>(
                        value: dropDownStringItem,
                        child: Text(dropDownStringItem),
                      );
                    }).toList(),
                    onChanged: (value) => _onSelectedState(value),
                    value: _selectedState,
                  ),
                ),
              );
            }),
          ),
          SizedBox(
            width: 10,
          ),
          Flexible(
            flex: 2,
            child: FormField(builder: (FormFieldState<String> state) {
              return InputDecorator(
                decoration: InputDecoration(
                    contentPadding: EdgeInsets.only(left: 10, right: 10),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0))),
                child: DropdownButtonHideUnderline(
                  child: DropdownButton<String>(
                    isExpanded: true,
                    items: _lgas.map((String dropDownStringItem) {
                      return DropdownMenuItem<String>(
                        value: dropDownStringItem,
                        child: Text(dropDownStringItem),
                      );
                    }).toList(),
                    onChanged: (value) => _onSelectedLGA(value),
                    value: _selectedLGA,
                  ),
                ),
              );
            }),
          ),
        ],
      ),
    );
  }
}

使用上面的代码,下拉菜单没有显示我通过 firebase 数据传递的任何动态数据。 它显示的只是我已经给出的数据.. 我尝试打印列表... 它显示了来自firebase的数据.. 但它没有显示在屏幕上

我试过调用 setState().. 还是没用...

我的状态模型

class StateModel {
  String state;
  String alias;
  List<String> lgas;

  StateModel({this.state, this.alias, this.lgas});

  StateModel.fromJson(Map<String, dynamic> json) {
    state = json['state'];
    alias = json['alias'];
    lgas = json['lgas'].cast<String>();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['state'] = this.state;
    data['alias'] = this.alias;
    data['lgas'] = this.lgas;
    return data;
  }
}

【问题讨论】:

    标签: firebase flutter dart drop-down-menu flutter-layout


    【解决方案1】:

    flutter中当你想用一些新数据更新UI时,你需要调用StatefulWidget的State类中的setState((){})方法。这告诉框架小部件的状态已经改变,并且应该重新绘制小部件。

    来自颤振文档here

    有状态小部件由两个类实现:StatefulWidget 的子类和 State 的子类。 状态类包含小部件的可变状态和小部件的 build() 方法。 当小部件的状态发生变化时,状态对象调用 setState(),告诉框架重绘小部件。

    所以在您上面的代码中,当您从 Firebase FireStore 接收数据并将其添加到相应的List 中时,您需要在将数据添加到列表后调用setState((){}) 方法。

    所以你的getData() 应该是这样的:

    void getdata() {
        Firestore.instance.collection("Categories").getDocuments().then((value) {
          setState((){
             _states.add(value.documents.last.data["state"]);
             _lgas.add((value.documents.last.data["lgas"][0]));
          });
    
          print((value.documents.last.data["lgas"]));
          print(value.documents.last.data);
        });
      }
    

    附注: 此外,调用setState((){}) 会重建小部件,以根据存在的数据更新 UI。当您执行.add() 时,数据已经添加到列表中,这就是您可以在列表中看到新数据的原因,但是 UI 仍然显示旧数据,因为小部件尚未重建以显示更新数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-03
      • 2021-05-17
      • 2011-09-24
      • 2016-11-19
      • 2021-03-24
      • 2021-12-12
      • 1970-01-01
      • 2014-08-10
      相关资源
      最近更新 更多