Передать параметр в initState - PullRequest
0 голосов
/ 06 марта 2019

Посмотрите на этот код - виджет для извлечения данных и отображения в списке:

class _MyEventsFragmentState extends State <MyEventsFragment>{

  var events;

  @override
  initState(){
    super.initState();
    events = fetchEvents(true);
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: FutureBuilder<EventsResponse>(
          future: events,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                helpers.logout(context, Strings.msg_session_expired);
                return CircularProgressIndicator();
              }
              return new Container(color: Colors.white,
                  child: new ListControl().build(snapshot));
            }
            return CircularProgressIndicator();
          },
        )
    );
  }
}

fetchEvent метод имеет параметр, чтобы указать, какие события мне нужно выбрать. Если установлено значение true, - мои события, если установлено значение false - все события возвращаются. Выше кода загружает мои события и fetchEvents вызывается внутри initState переопределения, чтобы избежать ненужной перезагрузки данных.

Чтобы получить все события, я определил другой класс:

class EventsFragment extends StatefulWidget {

  @override
  _EventsFragmentState createState() => new _EventsFragmentState();
}

class _EventsFragmentState extends State <EventsFragment>{

  var events;

  @override
  initState(){
    super.initState();
    events = fetchEvents(false);
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: FutureBuilder<EventsResponse>(
          future: events,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                helpers.logout(context, Strings.msg_session_expired);
                return CircularProgressIndicator();
              }
              return new Container(color: Colors.white,
                  child: new ListControl().build(snapshot));
            }
            return CircularProgressIndicator();
          },
        )
    );
  }
}

Но это очень глупое решение, потому что код практически одинаков. Поэтому я попытался передать логическое значение, чтобы указать, какие события загружать, что-то вроде этого:

@override
  initState(){
    super.initState();
    events = fetchEvents(isMyEvents);
  }

isMyEvents должен быть получен из EventsFragment конструктора. Однако, это не будет доступно внутри initState. Как пройти это правильно? Я мог получить к нему доступ внутри build override, но не внутри initState. Как правильно передать его и убедиться, что он будет обновляться при каждом создании экземпляра виджета?

[править]

Так вот как я решил свою проблему (вроде бы нормально):

class EventsFragment extends StatefulWidget {
  const EventsFragment({Key key, this.isMyEvent}) : super(key: key);

  final bool isMyEvent;

  @override
  _EventsFragmentState createState() => new _EventsFragmentState();
}

class _EventsFragmentState extends State <EventsFragment>{

  var events;

  @override
  initState(){
    super.initState();
    events = fetchEvents(widget.isMyEvent);
  }

  @override
  void didUpdateWidget(EventsFragment oldWidget) {

    if(oldWidget.isMyEvent != widget.isMyEvent)
      events = fetchEvents(widget.isMyEvent);

    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: FutureBuilder<EventsResponse>(
          future: events,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                helpers.logout(context, Strings.msg_session_expired);
                return CircularProgressIndicator();
              }
              return new Container(color: Colors.white,
                  child: new ListControl().build(snapshot));
            }
            return CircularProgressIndicator();
          },
        )
    );
  }
}

1 Ответ

2 голосов
/ 06 марта 2019

Передайте такой параметр в подкласс StatefulWidget и используйте это поле вместо

class Foo extends StatefulWidget {
  const Foo({Key key, this.isMyEvent}) : super(key: key);

  final bool isMyEvent;

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

class _FooState extends State<Foo> {
  @override
  void initState() {
    super.initState();
    print(widget.isMyEvent);
  }

  @override
  Widget build(BuildContext context) {
    return Container(

    );
  }
}
...