• Flutter 后台数据接口调试 业务分离


    建立数据模型层,我们的业务逻辑分开,然后进行后台数据的调试。按照真实项目的开发目录接口和文件组织来进行开发。

    建立商品详细模型

    我们还是用快速生成的方式建立一下商品详细页的接口模型,有这样一段从后端获取的JSON,直接用快速生成的方式,把这段JSON生成模型,然后进行必要的修改。

    {"code":"0","message":"success","data":{"goodInfo":{"image5":"","amount":10000,"image3":"","image4":"","goodsId":"ed675dda49e0445fa769f3d8020ab5e9","isOnline":"yes","image1":"http://images.baixingliangfan.cn/shopGoodsImg/20190116/20190116162618_2924.jpg","image2":"","goodsSerialNumber":"6928804011173","oriPrice":3.00,"presentPrice":2.70,"comPic":"http://images.baixingliangfan.cn/compressedPic/20190116162618_2924.jpg","state":1,"shopId":"402880e860166f3c0160167897d60002","goodsName":"可口可乐500ml/瓶","goodsDetail":"<img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081109_5060.jpg" width="100%" height="auto" alt="" /><img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081109_1063.jpg" width="100%" height="auto" alt="" /><img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081110_8029.jpg" width="100%" height="auto" alt="" /><img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081110_1074.jpg" width="100%" height="auto" alt="" /><img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081110_8439.jpg" width="100%" height="auto" alt="" /><img src="http://images.baixingliangfan.cn/shopGoodsDetailImg/20171224/20171224081110_6800.jpg" width="100%" height="auto" alt="" />"},"goodComments":[{"SCORE":5,"comments":"果断卸载,2.5个小时才送到","userName":"157******27","discussTime":1539491266336}],"advertesPicture":{"PICTURE_ADDRESS":"http://images.baixingliangfan.cn/advertesPicture/20190113/20190113134955_5825.jpg","TO_PLACE":"1"}}}

    复制上面的的代码,代开下面的地址,利用JSON代码,快速生成Model模型。

    https://javiercbk.github.io/json_to_dart/

    lib/model文件夹下新建立details.dart文件,然后把生成的代码拷贝到下面。

    class DetailsModel {
      String code;
      String message;
      DetailsGoodsData data;
    
      DetailsModel({this.code, this.message, this.data});
    
      DetailsModel.fromJson(Map<String, dynamic> json) {
        code = json['code'];
        message = json['message'];
        data = json['data'] != null ? new DetailsGoodsData.fromJson(json['data']) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['code'] = this.code;
        data['message'] = this.message;
        if (this.data != null) {
          data['data'] = this.data.toJson();
        }
        return data;
      }
    }
    
    class DetailsGoodsData {
      GoodInfo goodInfo;
      List<GoodComments> goodComments;
      AdvertesPicture advertesPicture;
    
      DetailsGoodsData({this.goodInfo, this.goodComments, this.advertesPicture});
    
      DetailsGoodsData.fromJson(Map<String, dynamic> json) {
        goodInfo = json['goodInfo'] != null
            ? new GoodInfo.fromJson(json['goodInfo'])
            : null;
        if (json['goodComments'] != null) {
          goodComments = new List<GoodComments>();
          json['goodComments'].forEach((v) {
            goodComments.add(new GoodComments.fromJson(v));
          });
        }
        advertesPicture = json['advertesPicture'] != null
            ? new AdvertesPicture.fromJson(json['advertesPicture'])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.goodInfo != null) {
          data['goodInfo'] = this.goodInfo.toJson();
        }
        if (this.goodComments != null) {
          data['goodComments'] = this.goodComments.map((v) => v.toJson()).toList();
        }
        if (this.advertesPicture != null) {
          data['advertesPicture'] = this.advertesPicture.toJson();
        }
        return data;
      }
    }
    
    class GoodInfo {
      String image5;
      int amount;
      String image3;
      String image4;
      String goodsId;
      String isOnline;
      String image1;
      String image2;
      String goodsSerialNumber;
      double oriPrice;
      double presentPrice;
      String comPic;
      int state;
      String shopId;
      String goodsName;
      String goodsDetail;
    
      GoodInfo(
          {this.image5,
          this.amount,
          this.image3,
          this.image4,
          this.goodsId,
          this.isOnline,
          this.image1,
          this.image2,
          this.goodsSerialNumber,
          this.oriPrice,
          this.presentPrice,
          this.comPic,
          this.state,
          this.shopId,
          this.goodsName,
          this.goodsDetail});
    
      GoodInfo.fromJson(Map<String, dynamic> json) {
        image5 = json['image5'];
        amount = json['amount'];
        image3 = json['image3'];
        image4 = json['image4'];
        goodsId = json['goodsId'];
        isOnline = json['isOnline'];
        image1 = json['image1'];
        image2 = json['image2'];
        goodsSerialNumber = json['goodsSerialNumber'];
        oriPrice = json['oriPrice'];
        presentPrice = json['presentPrice'];
        comPic = json['comPic'];
        state = json['state'];
        shopId = json['shopId'];
        goodsName = json['goodsName'];
        goodsDetail = json['goodsDetail'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['image5'] = this.image5;
        data['amount'] = this.amount;
        data['image3'] = this.image3;
        data['image4'] = this.image4;
        data['goodsId'] = this.goodsId;
        data['isOnline'] = this.isOnline;
        data['image1'] = this.image1;
        data['image2'] = this.image2;
        data['goodsSerialNumber'] = this.goodsSerialNumber;
        data['oriPrice'] = this.oriPrice;
        data['presentPrice'] = this.presentPrice;
        data['comPic'] = this.comPic;
        data['state'] = this.state;
        data['shopId'] = this.shopId;
        data['goodsName'] = this.goodsName;
        data['goodsDetail'] = this.goodsDetail;
        return data;
      }
    }
    
    class GoodComments {
      int sCORE;
      String comments;
      String userName;
      int discussTime;
    
      GoodComments({this.sCORE, this.comments, this.userName, this.discussTime});
    
      GoodComments.fromJson(Map<String, dynamic> json) {
        sCORE = json['SCORE'];
        comments = json['comments'];
        userName = json['userName'];
        discussTime = json['discussTime'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['SCORE'] = this.sCORE;
        data['comments'] = this.comments;
        data['userName'] = this.userName;
        data['discussTime'] = this.discussTime;
        return data;
      }
    }
    
    class AdvertesPicture {
      String pICTUREADDRESS;
      String tOPLACE;
    
      AdvertesPicture({this.pICTUREADDRESS, this.tOPLACE});
    
      AdvertesPicture.fromJson(Map<String, dynamic> json) {
        pICTUREADDRESS = json['PICTURE_ADDRESS'];
        tOPLACE = json['TO_PLACE'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['PICTURE_ADDRESS'] = this.pICTUREADDRESS;
        data['TO_PLACE'] = this.tOPLACE;
        return data;
      }
    }

    添加商品详情的接口

    'getGoodDetailById':serviceUrl+'wxmini/getGoodDetailById',//商品详细信息

    Provide建立

    在实际开发中,我们是将业务逻辑和UI表现分开的,所以线建立一个Provide文件,所有业务逻辑将写在Provide里,然后pages文件夹里只写UI层面的东西。这样就把业务逻辑和UI进行了分离。

    lib/provide/文件夹下新建立一个details_info.dart文件,这个文件就是写商品详细页相关的业务逻辑的。

    import 'package:flutter/material.dart';
    import '../model/details.dart';
    import '../service//service_method.dart';
    import 'dart:convert/';
    
    class DetailsInfoProvide with ChangeNotifier{ 
      DetailsModel goodsInfo = null; //商品详情的变量
    
      //从后台获取商品数据
      getGoodsInfo(String id){ //传递商品id
        var formData = {'goodId':id};
        request('getGoodDetailById', formData: formData).then((val){
          var responseData = json.decode(val.toString()); //从后台得到的数据
          print(responseData);
          goodsInfo = DetailsModel.fromJson(responseData);
          notifyListeners(); //通知
    
        });
    
      }
    
    }

    先引入刚建立好的Model,然后引入service_method.dart文件。声明DetailsInfoProvidel类,在类里边声明一个DetailsModel类型的 goodsInfo变量,初始值甚至成null,然后写一个从后台获取数据的方法,命名为getGoodsInfo

    Provide全局注入

    在main.dart中注入,先引入details_info.dart文件,然后声明变量、注入

    var detailsInfoProvide = DetailsInfoProvide();
    ..provide(Provider<DetailsInfoProvide>.value(detailsInfoProvide));

    在UI调试接口

    直接在pages文件夹的details_page.dart文件里,写一个_getBackInfo方法,然后在build方法里使用一下。 如果控制台打印出商品详细的数据,说明接口已经调通。

      void _getBackInfo(BuildContext context) async{
        await Provide.value<DetailsInfoProvide>(context).getGoodsInfo(goodsId);
        print('加载完成...........');
      }

    完整代码:

    import 'package:flutter/material.dart';
    import 'package:provide/provide.dart';
    import '../provide/detail_info.dart';
    
    class DetailsPage extends StatelessWidget {
      final String goodsId;
      DetailsPage(this.goodsId); //构造函数最新写法
    
      @override
      Widget build(BuildContext context) {
        _getBackInfo(context);
        return Container(
          child: Center(
            child: Text('商品ID:${goodsId}'),
          ),
        );
      }
    
      void _getBackInfo(BuildContext context) async{
        await Provide.value<DetailsInfoProvide>(context).getGoodsInfo(goodsId);
        print('加载完成...........');
      }
    
    }

    运行测试,控制台成功打印出商品详细的数据,说明接口已经调通。

    详细页UI主页面架构搭建

    details_page页面主要修改build方法。代码如下:

    Widget build(BuildContext context) {
        
        return Scaffold(
          appBar: AppBar(
            leading: IconButton( //返回按钮
              onPressed: (){
                Navigator.pop(context); //返回上级页面
              },
              icon: Icon(Icons.arrow_back),
            ),
            title: Text('商品详细页'),
          ),
          body: FutureBuilder(
            future: _getBackInfo(context),
            builder: (context, snapshot){
              if(snapshot.hasData){
                return Container(
                  child: Column(
                    children: <Widget>[
                      Text('商品ID:${goodsId}')
                    ],
                  ),
                );
              }else{
                return Text('加载中......');
              }
            },
          ),
        );
      }

    在body区域,使用了FutureBuilder Widget ,可以实现异步建在的效果。并且在可以判断snapshot.hasData进行判断是否在加载还是在加载中。

    _getBackInfo方法的修改

    在build方法里使用了FutureBuilder部件,所以使用的后台得到数据的方法,也要相应的做出修改,要最后返回一个Future 部件。代码如下:

    Future _getBackInfo(BuildContext context) async{
        await Provide.value<DetailsInfoProvide>(context).getGoodsInfo(goodsId);
        return '完成加载';
    }

    完整代码如下:

    import 'package:flutter/material.dart';
    import 'package:provide/provide.dart';
    import '../provide/detail_info.dart';
    
    class DetailsPage extends StatelessWidget {
      final String goodsId;
      DetailsPage(this.goodsId); //构造函数最新写法
    
      @override
      Widget build(BuildContext context) {
        
        return Scaffold(
          appBar: AppBar(
            leading: IconButton( //返回按钮
              onPressed: (){
                Navigator.pop(context); //返回上级页面
              },
              icon: Icon(Icons.arrow_back),
            ),
            title: Text('商品详细页'),
          ),
          body: FutureBuilder(
            future: _getBackInfo(context),
            builder: (context, snapshot){
              if(snapshot.hasData){
                return Container(
                  child: Column(
                    children: <Widget>[
                      Text('商品ID:${goodsId}')
                    ],
                  ),
                );
              }else{
                return Text('加载中......');
              }
            },
          ),
        );
      }
    
      Future _getBackInfo(BuildContext context) async{
        await Provide.value<DetailsInfoProvide>(context).getGoodsInfo(goodsId);
        return '完成加载';
      }
    
    }
  • 相关阅读:
    Cesium案例解析(二)——ImageryLayers影像图层
    Cesium案例解析(一)——HelloWorld
    WebGL简易教程(十四):阴影
    WebGL简易教程(十三):帧缓存对象(离屏渲染)
    关于GDAL读写Shp乱码的问题总结
    WebGL简易教程(十二):包围球与投影
    GDAL集成对KML文件的支持
    WebGL简易教程(十一):纹理
    WebGL简易教程(十):光照
    WebGL简易教程(九):综合实例:地形的绘制
  • 原文地址:https://www.cnblogs.com/joe235/p/11310427.html
Copyright © 2020-2023  润新知