微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter:ChangeNotifierProvider 不适用于我的 MVVM 架构

如何解决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 举报,一经查实,本站将立刻删除。