用户更改数据后,UI 不会使用Provider
更新数据。API 调用始终statusCode: 200
但除非我再次刷新/构建页面,否则 UI 不会更新。我假设设置状态方法没有被我正确设置,但我不确定我做错了什么。代码:
编辑个人资料信息的方法:
Map<String, dynamic> userData;
@override
Widget build(BuildContext context) {
UserData user = UserData.fromJson(userData);
return TextButton(
onPressed: () async {
changeUserInfo(user) // I pass the user object to the method
.whenComplete(() => Navigator.of(context).pop());
},
child: Text(
'SAVE',
),
);
}
更改用户方法:
Future<void> changeUserInfo(UserData user) async {
final userRes = await patchUserInfo(user); // API CALL WHICH ALWAYS GOES THROUGH
if (userRes != null) {
// HERE IS WHERE I WANT TO SET THE CURRENT STATE OF THE USER THAT HAS BEEN CHANGED
userStore.setUserInfo(user);
return;
}
}
用户存储:
class UserStore extends ChangeNotifier {
Map<String, UserData> _userInfo = {};
Map<String, UserData> get userInfo => _userInfo ;
void setUserInfo(UserData user) {
_userInfo[user.id] = user; // I assume this is where I do something wrong?!
notifyListeners();
}
UserData getUserInfoByUserId(String userId) => _userInfo[userId];
}
这是补丁后返回的 API 中的 JSON:
{
"statusCode": 200,
"message": "Success",
"data": {
"id": "1",
"email": "johndoe@johndoe.com",
"firstName": "John",
"lastName": "Doe",
}
}
和我的用户模型:
class UserData {
String id, firstName,
lastName,
email;
UserData({
this.id,
this.firstName,
this.lastName,
this.email,
});
UserData.fromJson(Map<String, dynamic> json) {
id = json['id'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = this.id;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['email'] = this.email;
return data;
}
}
假设我应该看到更改的屏幕(我甚至尝试过Consumer
,所以它是相同的):
class SomeClassExample extends StatelessWidget {
final userStore = Provider.of<UserStore>(context, listen: false);
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
现在的设置方式(或者至少我认为是这样),我将user
对象传递给changeUserInfo
方法,其中对象传递给 API 调用,如果返回的 API 调用未null
,则使用传递的对象设置用户信息的当前状态。然后在存储中,我将该对象传递到我的UserData
映射中,通知侦听器,在侦听的位置更新它,仅此而已。我不确定我做错了什么。
提前感谢您的帮助。
在这一行:
final userStore = Provider.of<UserStore>(context, listen: false);
请改用listen: true
。
这应该使它更新。
根据文档,listen: false
标志允许您从提供程序存储中读取值,而无需观察其更改。它通常用于优化应用程序以避免不必要的重建。
为什么不将列包装在侦听UserStore的消费者小部件中。
你是这样做的吗:
// remove fetching the provider using Provider.of;
// the Consumer widget is taking care of that for you.
return Consumer<UserStore>(
builder: (context, userStore, child) {
UserData user = userStore.getUserInfo(userId);
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
);
每次在用户存储上调用notifyListeners时,它都应该导致此小部件自行重建,并显示更改。 现在,您也没有显示从何处获取userId,我现在也想知道。
突出显示的行
您的 JSON 和用户数据对象使用UserData.id
成员,但突出显示的行_userInfo[user.userId] = user;
使用userId
。如果提供的类定义是正确的,则应user.id
。
其他提供者的东西,也许
您可以使用 context.watch 而不是 Provider.of,但如果 Consumer 不起作用,那么它不太可能改变任何东西。(代码块中编写的提供程序不会触发重新呈现)
final userStore = context.watch<UserStore>();
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
请记住在小部件树中插入提供程序
也许确保提供程序已正确插入到小部件树中 - 上面的代码示例不包括确切的代码。如果缺少它,那么它应该是什么样子的近似值如下:
ChangeNotifierProvider(create: (context) => UserStore(), SomeParentWidget())