Инициализирующая переменная в initState - PullRequest
0 голосов
/ 07 июня 2019

Я инициализирую переменную в initState(){}:

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

    });
  }

Метод является асинхронным и в основном получает данные из Firestore, чтобы заполнить объект '_markerMap' данными. Это свойство затем используется как свойство в виджете. И этот виджет вызывается в моем build методе.

Widget build(BuildContext context) {
    return new Scaffold(
      body: MyWidget(
            markerMap: _markerMap)
     );
  ....
 }

MyWidget - это календарь. markerMaps добавляет значки к определенным датам в календаре. Маркеры только иногда добавляются в календарь. Так что сбой прерывистый. Можно с уверенностью предположить, что в initState() данные будут загружаться из firestore для инициализации переменной из Firestore. Есть мысли, что может происходить и почему только иногда маркеры появляются в календаре?

добавление кода с установленным _markerMap

getDataFromFirestore() async {
    await FirebaseAuth.instance.currentUser().then((user) {
      Firestore.instance.collection('availableDates').where('bandId', isEqualTo: user.uid).snapshots().listen(
              (data) => data.documents.forEach((doc) => _markerMap.add(
              doc['availableDates'].toDate(),
              Event(
                  date:doc['availableDates'].toDate(),
                  title: 'hello',
                  icon: _presentIcon(doc['availableDates'].toDate().day.toString())))));
      setState(() {});
    }).catchError((onError){
    });
  }

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Как я вижу из вашего getDataFromFirestore метода, вы выполняете перестройку виджета (setState вызов) сразу после получения объекта User (FirebaseAuth.instance.currentUser() вызов).

Однако позже вы изменяете переменную _markerMap - только после завершения запроса Firestore.instance.collection. В этом случае setState вызов, где он находится сейчас, является излишним.

Вызов setState внутри вашего listen обратного вызова должен решить проблему.

, например

final _markerMap = {};

getDataFromFirestore() async {
  await FirebaseAuth.instance.currentUser().then((user) {
    Firestore.instance
      .collection('availableDates')
      .where('bandId', isEqualTo: user.uid)
      .snapshots()
      .listen((data) => data.documents.forEach((doc) {
        setState(() { // Here is the setState call
          _markerMap.add(
            doc['availableDates'].toDate(),
            Event(
              date: doc['availableDates'].toDate(),
              title: 'hello',
              icon: _presentIcon(doc['availableDates'].toDate().day.toString())
            )
          );
        });
      }));
  }).catchError((onError) {});
}

Пожалуйста, проверьте этот пример кода. Мой общий совет верен, однако я не проверял это на своем конце.

1 голос
/ 07 июня 2019

Нет ничего плохого в инициализации переменных в initState, если они не являются статическими.Итак, что происходит, вы изначально объявили _markerMap, но он будет инициализирован только после некоторой асинхронной функции getDataFromFirestore (), которая может занять несколько секунд.И здесь вы присвоили markerMap: _markerMap, но изначально _markerMap имеет значение null и инициализируется только после функции getDataFromFirestore ().Поэтому хорошей практикой является либо проверка на null

_markerMap!=null?MyWidget(
            markerMap: _markerMap):Container();

, либо предоставление значения по умолчанию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...