将参数传递给 initState

Posted

技术标签:

【中文标题】将参数传递给 initState【英文标题】:Pass parameter to initState 【发布时间】:2019-07-28 00:02:36 【问题描述】:

查看这段代码 - 获取数据并显示在列表中的小部件:

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 - 返回所有事件。上面的代码会加载我的事件,并在 initState 覆盖内调用 fetchEvents 以避免不必要的数据重新加载。

为了获取所有事件,我定义了另一个类:

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 覆盖内访问它,但不能在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();
          ,
        )
    );
  

【问题讨论】:

将你的参数保存为finalEventsFragment中的字段 无法从状态访问 是的,它会的,见State#widgetproperty 【参考方案1】:

将此类参数传递给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(

    );
  

【讨论】:

initState() 仅被调用一次,因此如果我第一次将 isMyEvent 传递为 true,然后第二次传递为 false,我的数据将不会被刷新。如何从我的小部件外部强制重置状态? 我的意思是颤振缓存我的小部件。因此,如果我想再次显示它,更改 isMyEvent 值,仍然会使用以前的 isMyEvent 值刷新数据。 使用didUpdateWidget 怎么用?我将didUpdateWidget(widget); 添加到initState,但我仍然遇到同样的问题 我更新了我的问题,如果它是有效的解决方案,请告诉我。

以上是关于将参数传递给 initState的主要内容,如果未能解决你的问题,请参考以下文章

如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]

Excel VBA - 将参数参数传递给 Sub

将参数传递给 Bamboo 中的构建

java中,如何用POST方法将参数传递给第三方网站

将参数传递给页面,数据不更新

将对象作为参数传递给函数