如何解决Flutter:ChangeNotifierProvider 不适用于我的 MVVM 架构
我有一个复杂的 JSON 对象,我已经使用 JSON to Dart 插件将它转换为 dart 代码。我创建了一个视图模型来调用我的 API 并更新提供者。但是,提供程序似乎不起作用。 API 响应成功,但我收到此错误消息 -> 在构建 Builder 时抛出了以下 NoSuchMethodError:getter 'replyStatus' 在 null 上被调用。接收者:空尝试调用:replyStatus
谁能帮我解决这个问题?
下面是我的代码。
JSON 到 Dart 响应
class UserProfile {
int replyStatus;
String replyDesc;
int debugStep;
bool hasData;
int actualDataSize;
List<ResultObjectSet> resultObjectSet;
dynamic token;
UserProfile(
{this.replyStatus,this.replyDesc,this.debugStep,this.hasData,this.actualDataSize,this.resultObjectSet,this.token});
UserProfile.fromJson(Map<String,dynamic> json) {
replyStatus = json['ReplyStatus'];
replyDesc = json['ReplyDesc'];
debugStep = json['DebugStep'];
hasData = json['HasData'];
actualDataSize = json['ActualDataSize'];
if (json['ResultObjectSet'] != null) {
// ignore: deprecated_member_use
resultObjectSet = new List<ResultObjectSet>();
json['ResultObjectSet'].forEach((v) {
resultObjectSet.add(new ResultObjectSet.fromJson(v));
});
}
token = json['Token'];
}
Map<String,dynamic> toJson() {
final Map<String,dynamic> data = new Map<String,dynamic>();
data['ReplyStatus'] = this.replyStatus;
data['ReplyDesc'] = this.replyDesc;
data['DebugStep'] = this.debugStep;
data['HasData'] = this.hasData;
data['ActualDataSize'] = this.actualDataSize;
if (this.resultObjectSet != null) {
data['ResultObjectSet'] =
this.resultObjectSet.map((v) => v.toJson()).toList();
}
data['Token'] = this.token;
return data;
}
}
class ResultObjectSet {
String objectName;
ObjectSet objectSet;
ResultObjectSet({this.objectName,this.objectSet});
ResultObjectSet.fromJson(Map<String,dynamic> json) {
objectName = json['ObjectName'];
objectSet = json['ObjectSet'] != null
? new ObjectSet.fromJson(json['ObjectSet'])
: null;
}
Map<String,dynamic>();
data['ObjectName'] = this.objectName;
if (this.objectSet != null) {
data['ObjectSet'] = this.objectSet.toJson();
}
return data;
}
}
class ObjectSet {
int userId;
String userName;
String regsterEmail;
String lastLogin;
double displayTimeZone;
int accountStatus;
int language;
List<UserCompany> userCompany;
MenuOption menuOption;
bool pnmdisableFlag;
ObjectSet(
{this.userId,this.userName,this.regsterEmail,this.lastLogin,this.displayTimeZone,this.accountStatus,this.language,this.userCompany,this.menuOption,this.pnmdisableFlag});
ObjectSet.fromJson(Map<String,dynamic> json) {
userId = json['UserId'];
userName = json['UserName'];
regsterEmail = json['RegsterEmail'];
lastLogin = json['LastLogin'];
displayTimeZone = json['displayTimeZone'];
accountStatus = json['AccountStatus'];
language = json['Language'];
if (json['UserCompany'] != null) {
// ignore: deprecated_member_use
userCompany = new List<UserCompany>();
json['UserCompany'].forEach((v) {
userCompany.add(new UserCompany.fromJson(v));
});
}
menuOption = json['MenuOption'] != null
? new MenuOption.fromJson(json['MenuOption'])
: null;
pnmdisableFlag = json['PnmdisableFlag'];
}
Map<String,dynamic>();
data['UserId'] = this.userId;
data['UserName'] = this.userName;
data['RegsterEmail'] = this.regsterEmail;
data['LastLogin'] = this.lastLogin;
data['displayTimeZone'] = this.displayTimeZone;
data['AccountStatus'] = this.accountStatus;
data['Language'] = this.language;
if (this.userCompany != null) {
data['UserCompany'] = this.userCompany.map((v) => v.toJson()).toList();
}
if (this.menuOption != null) {
data['MenuOption'] = this.menuOption.toJson();
}
data['PnmdisableFlag'] = this.pnmdisableFlag;
return data;
}
}
class UserCompany {
int companyId;
String companyName;
int typeUserRoleId;
String typeUserRoleDesc;
int menuRights;
int reportRights;
ManagementCompanyRights managementCompanyRights;
ManagementCompanyRights managementUserRights;
ManagementCompanyRights managementUserRole;
ManagementCompanyRights managementFleetRights;
ManagementCompanyRights managementShipRights;
UserCompany(
{this.companyId,this.companyName,this.typeUserRoleId,this.typeUserRoleDesc,this.menuRights,this.reportRights,this.managementCompanyRights,this.managementUserRights,this.managementUserRole,this.managementFleetRights,this.managementShipRights});
UserCompany.fromJson(Map<String,dynamic> json) {
companyId = json['CompanyId'];
companyName = json['CompanyName'];
typeUserRoleId = json['TypeUserRoleId'];
typeUserRoleDesc = json['TypeUserRoleDesc'];
menuRights = json['MenuRights'];
reportRights = json['ReportRights'];
managementCompanyRights = json['ManagementCompanyRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementCompanyRights'])
: null;
managementUserRights = json['ManagementUserRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementUserRights'])
: null;
managementUserRole = json['ManagementUserRole'] != null
? new ManagementCompanyRights.fromJson(json['ManagementUserRole'])
: null;
managementFleetRights = json['ManagementFleetRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementFleetRights'])
: null;
managementShipRights = json['ManagementShipRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementShipRights'])
: null;
}
Map<String,dynamic>();
data['CompanyId'] = this.companyId;
data['CompanyName'] = this.companyName;
data['TypeUserRoleId'] = this.typeUserRoleId;
data['TypeUserRoleDesc'] = this.typeUserRoleDesc;
data['MenuRights'] = this.menuRights;
data['ReportRights'] = this.reportRights;
if (this.managementCompanyRights != null) {
data['ManagementCompanyRights'] = this.managementCompanyRights.toJson();
}
if (this.managementUserRights != null) {
data['ManagementUserRights'] = this.managementUserRights.toJson();
}
if (this.managementUserRole != null) {
data['ManagementUserRole'] = this.managementUserRole.toJson();
}
if (this.managementFleetRights != null) {
data['ManagementFleetRights'] = this.managementFleetRights.toJson();
}
if (this.managementShipRights != null) {
data['ManagementShipRights'] = this.managementShipRights.toJson();
}
return data;
}
}
class ManagementCompanyRights {
bool add;
bool edit;
bool delete;
bool fleetAssignment;
ManagementCompanyRights(
{this.add,this.edit,this.delete,this.fleetAssignment});
ManagementCompanyRights.fromJson(Map<String,dynamic> json) {
add = json['Add'];
edit = json['Edit'];
delete = json['Delete'];
fleetAssignment = json['FleetAssignment'];
}
Map<String,dynamic>();
data['Add'] = this.add;
data['Edit'] = this.edit;
data['Delete'] = this.delete;
data['FleetAssignment'] = this.fleetAssignment;
return data;
}
}
class MenuOption {
bool dashBoard;
bool fuelCons;
bool bunkering;
bool aMS;
bool shaftPower;
bool kpiPerformance;
bool eOM;
bool route;
bool report;
bool management;
MenuOption(
{this.dashBoard,this.fuelCons,this.bunkering,this.aMS,this.shaftPower,this.kpiPerformance,this.eOM,this.route,this.report,this.management});
MenuOption.fromJson(Map<String,dynamic> json) {
dashBoard = json['DashBoard'];
fuelCons = json['FuelCons'];
bunkering = json['Bunkering'];
aMS = json['AMS'];
shaftPower = json['ShaftPower'];
kpiPerformance = json['KpiPerformance'];
eOM = json['EOM'];
route = json['Route'];
report = json['Report'];
management = json['Management'];
}
Map<String,dynamic>();
data['DashBoard'] = this.dashBoard;
data['FuelCons'] = this.fuelCons;
data['Bunkering'] = this.bunkering;
data['AMS'] = this.aMS;
data['ShaftPower'] = this.shaftPower;
data['KpiPerformance'] = this.kpiPerformance;
data['EOM'] = this.eOM;
data['Route'] = this.route;
data['Report'] = this.report;
data['Management'] = this.management;
return data;
}
}
Main.Dart
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => UserVM(),),],child: MaterialApp(
initialRoute: LoginScreen.id,routes: {
LoginScreen.id: (context) => LoginScreen(),SelectCompany.id: (context) => SelectCompany(),},);
}
}
我的 API 类
class LoginScreenApi {
var dio = dio();
Future<UserProfile> authenticateUser(
String email,String password,String token) async {
try {
String queryURL =
'$domainURL/User/LoginMobile?Email=$email&UserPassword=$password&MobileDevicetokenId=$token';
Response response = await dio.get(queryURL);
print('login status: ${response.statusCode}');
if (response.statusCode == 200) {
UserProfile user = UserProfile.fromJson(response.data);
return user;
}
return null;
} catch (e) {
print(e);
return null;
}
}
}
我的虚拟机课程
class UserVM extends ChangeNotifier {
UserProfile user;
UserVM({this.user});
/// Call Login API
Future<void> authenticateUser(
String email,String token) async {
final results =
await LoginScreenApi().authenticateUser(email,password,token);
/// if login successfully,save the USER result and route to select company page
if (results != null) {
this.user = results;
notifyListeners();
Navigator.pushNamed(navigatorKey.currentContext,SelectCompany.id);
} else {
showDialog(
context: navigatorKey.currentContext,builder: (BuildContext context) {
return PopUpDialog(
text: 'Wrong User ID or Password!',);
});
}
}
}
我显示来自我的提供者的数据的屏幕
class _SelectCompanyState extends State<SelectCompany> {
@override
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text(
'${Provider.of<UserVM>(context,listen: false).replyStatus}',style: TextStyle(color: Colors.black),);
}
}
在我的登录屏幕上调用 Authenticate 方法的 Widget
Widget _loginButton() {
// ignore: deprecated_member_use
return RaisedButton(
onpressed: () async {
await user.authenticateUser(email,devicetoken);
setState(() {
showSpinner = true;
});
},color: Colors.black,child: Text(
'${userLanguage == 'chinese' ? '登入' : 'Login'}',style:
TextStyle(fontSize: 15,color: Colors.yellow,fontFamily: 'Roboto'),shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.lightBlueAccent)),);
}
解决方法
以下行加载您的 UserVM 实例。
final userVM = Provider<UserVM>.of(context,listen:false);
您的 UserVM 类没有名为 replyStatus 的属性,而是您的 UserProfile 类。所以这样称呼它:
final replyStatus = userVM.user.replyStatus;
注意:您的用户也可以为空,因为您在创建 UserVM() 时没有传递它。您也没有调用用户的身份验证方法来更新结果。如果您正在代码中的其他地方处理该问题,那么您还需要在调用之前检查用户是否为空:
final replyStatus;
If(userVM.user! = null) replyStatus = userVM.user.replyStatus;
else //<-- some alternative here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。