如何确保ScopedModelDescendant状态已更新?

时间:2019-03-28 22:59:55

标签: flutter scoped-model

我正在编写具有基本CRUD功能的Flutter应用程序。 我有用于显示项目列表,项目明细视图和编辑项目表单的屏幕。

当我从列表视图中点击项目的详细信息屏幕时,在最初创建项目后(使用单独的表单)数据可以正确呈现。

当我点击编辑表单时,从该详细信息屏幕中,该项目的数据将通过并预先填充在表单中。

当我对该项目的数据进行更改并保存更改时,我将返回到详细信息视图,但是该视图中的任何细节都没有更改。

但是,当我再上一层树时,列表视图中的项目已更新。

我在这里想念什么?如果具有scopedModel的父窗口小部件具有状态更改并由notifyListener()通知,那不应该沿着窗口小部件树顺流吗?

列表视图:

class GiftListDisplayWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<GiftList>(
      builder: (context, child, giftList) => ListView(
        children: giftList.gifts.map((Gift gift) => GiftCard(gift)).toList(),
      )
    );
  }
}

详细信息视图(为简洁起见,省略了一些代码)

class GiftDetailPage extends StatefulWidget {
  final Gift gift;

  GiftDetailPage(this.gift);

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

class _GiftDetailPageState extends State<GiftDetailPage> {
  Widget get giftProfile {
    return ListView(
      children: [titleSection, textSection, buttonSection, metadataSection],
    );
  }

  Widget get titleSection {...}

  Widget get textSection {...}

  Widget get buttonSection {
    return Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          FlatButton(...)
          FlatButton(
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => EditGiftFormPage(widget.gift)));
            },
            padding: EdgeInsets.all(10.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(Icons.edit, color: Colors.indigoAccent),
                Container(
                  margin: const EdgeInsets.only(top: 8.0),
                  child: Text(
                    'EDIT',
                    style: TextStyle(
                      fontSize: 12.0,
                      fontWeight: FontWeight.w400,
                      color: Colors.indigoAccent,
                    ),
                  ),
                ),
              ],
            ),
          ),
          FlatButton(...)
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget get metadataSection {...}

  _launchURL() async {...}

  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<GiftList>(
      builder: (context, child, giftList) => Scaffold(
            appBar: AppBar(
              title: Text('Gift Details'),
            ),
            body: giftProfile,
          ),
    );
  }
}

在编辑表单屏幕中:

class EditGiftFormPage extends StatefulWidget {
  final Gift existingGift;

  EditGiftFormPage(this.existingGift);

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

class _EditGiftFormPageState extends State<EditGiftFormPage> {
  TextEditingController nameController = TextEditingController();
  TextEditingController statusController = TextEditingController();
  TextEditingController descriptionController = TextEditingController();

  GiftStatus selectedStatus;

  Gift updatedGift;

  @override
  void initState() {
    nameController.text = widget.existingGift.recipient;
    selectedStatus = widget.existingGift.giftStatus;
    descriptionController.text = widget.existingGift.recipient;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Gift'),
      ),
      body: ScopedModelDescendant<GiftList>(
        builder: (context, child, giftList) => Container(
              color: Colors.white,
              child: Padding(
                padding: const EdgeInsets.symmetric(
                  vertical: 8.0,
                  horizontal: 32.0,
                ),
                child: Column(...),
              ),
            ),
      ),
    );
  }

  save(GiftList giftList) {
    if (nameController.text.isEmpty ||
        descriptionController.text.isEmpty ||
        selectedStatus == null) {
      print('Make sure you have completed the form');
    } else {
      var newGift = Gift(
          id: widget.existingGift.id,
          recipient: nameController.text,
          giftStatus: selectedStatus,
          description: descriptionController.text,
          imageUrl: 'https://picsum.photos/1080/608/?random');
      giftList.update(newGift);
      Navigator.of(context).pop();
    }
  }
}

到目前为止,我已经写完了,我希望所有这些组件都关心giftList模型,因此它们应该在监听该模型,并且giftList.update被表单调用,它们都应该重新渲染。

当前,只有顶层列表视图显示更新后的数据,状态并没有通过两个子窗口小部件。

我的知识上显然有差距,如果有人可以看到它,我很想知道!

0 个答案:

没有答案