【问题标题】:ScopedModelDescendant String returns null. Not retrieving stateScopedModelDescendant 字符串返回 null。不检索状态
【发布时间】:2019-06-06 17:28:52
【问题描述】:

我正在重构应用程序以使用 scoped_model 但有问题。小部件之间的状态似乎不正确。

我首先在启动时将ScopedModel 添加到小部件树的顶部。:

 @override
  Widget build(BuildContext context) {

    UserModel().initialiseValues();

    return ScopedModel<UserModel>(
      model: UserModel(),

    child: MaterialApp(
        home: new Page(),
    ),
    );
  }

此调用.initialiseValues();,因此模型从SharedPreferences 读取并存储在变量中:

class UserModel extends Model {

  String _name;
  String get name => _name;

void initialiseValues() async {
    SharedPreferences sharedPrefs = await SharedPreferences.getInstance();

_name = sharedPrefs.getString('name');
print(‘_name from sharedPrefs is $_name');
print(‘name from sharedPrefs is $name');


notifyListeners();
}
}

两个打印语句都返回正确的名称。

但是当我尝试在另一个页面中使用ScopedModelDescendant 调用name 时返回null:

class PageFive extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

  return ScopedModelDescendant<UserModel>(

    builder: (context, child, model) =>

Text('${model.name}'),

    );

  }
}

Text('${model.name}'),返回null

有人知道为什么name 返回null吗? 我一直在努力寻找解决方案,但不知道为什么。

【问题讨论】:

  • @pskink 是的。谢谢。我有更新问题。我不知道为什么_name 在调用时为空。

标签: dart flutter state state-management


【解决方案1】:

好像有两个问题:

1.- 当方法不是静态的时,您以静态方式调用 .initialiseValues()。然后在ScopedModel 中创建一个新的不同的UserModel

2.- 您正在第一个 build() 方法中调用 async 函数,但您不确定它何时会完成,并且可能在构建树时 UserModel 未完全初始化。

您可能应该有一个布尔变量(或检查 .name 是否为空)并在初始化时将其设置为 true。

在 build 方法中,如果该变量为 false,您可以返回 CircularProgressIndicator,如果为 true,则返回您的小部件。

@override
Widget build(BuildContext context) {

  var userModel = UserModel()..initialiseValues();

  return ScopedModel<UserModel>(
    model: userModel,
    child: MaterialApp(
      home: new Page(),
    ),
  );
}

class PageFive extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return ScopedModelDescendant<UserModel>(
    builder: (context, child, model) {
       if (model.name == null)
          return CircularProgressIndicator();
       else
          return Text('${model.name}');
    });
  }
}

【讨论】:

  • 感谢您的回复!但我不认为这是问题所在。我可以从 print 语句中看到 UserModel 已完全初始化。
  • 是的,但是print语句在initialise方法内部,在await调用之后它不为null是正常的。试试我添加的新代码。
  • 谢谢。我已经尝试过你的代码,但 CircularProgressIndicator 处于循环状态并且没有停止
  • 我看到了问题。我已经编辑了答案。问题一定出在您创建UserModel() 并调用initialiseValues() 的方式上
  • 感谢您的回复!你能解释更多问题1吗? '当方法不是静态时,你以静态方式调用 .initialiseValues()' 是什么意思?
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 2014-07-28
  • 2012-10-09
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
相关资源
最近更新 更多