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

Posted joe235

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 完成加载;
  }

}

 

以上是关于Flutter 后台数据接口调试 业务分离的主要内容,如果未能解决你的问题,请参考以下文章

做前后台代码分离项目的一些好的习惯

前后台分离h5和后台数据接口怎么交互数据的

浅谈前后端分离。

Web项目开发为何要走前后端分离模式?

前后端分离怎么获取后台接口数据

平台技术框架的基本思路:基本原则