关于原因:客户端 和web端的同学共同开一个一新的Flutter项目,客户端在使用接口时习惯性使用 (api-model-view)而web同学直接适应(api-view),这样独立开发自己模块本来是没什么问题的,结果到后面设计到交互那就贼尴尬啊。
Web端:你传输入是能不能给我个json啊
客户端:我们一般都转成model了你在转一下把
结果就这么多了一些转换的代码和不必要的问题
先说下由没有Model到使用model的转化
最早的前端是不关心数据的,界面上的内容都是固定,像一张照片,而且不是哈利波特中那种会动的照片。
稍微进阶一点的话,就是注入 PHP 或者 JSP 之类的变量占位,但是其实和写固定数据是一样。
就像去饭店吃饭,你不用关心主料配菜的比例是多少,你拿到的就是加工好的菜品了,直接可以吃。
继续往前看,当通过 ajax 拿到数据,比如表格数据,我们稍加修饰就可以展示出来,好像也没有很强烈的需求要在本地管理。这就像涮羊肉,你需要自己去烫熟它,但是基本上从头到尾都不松筷子,涮一下(从服务器拉一下),蘸一下(处理一下格式),就可以吃(展示)了。
但是随着数据越来越多,远端数据之间存在逻辑关系的时候,你就不得不自己动手加工了。比如去自助烤肉店,你想吃培根金针菇卷,但是后厨(后台)说,我们懒得弄这东西了,你自己动手搞吧。你就要自己去拿培根和金针菇,自己卷起来。
所以和饮食一样,从原料(原始数据)到成品(页面展现),中间的加工过程是确定的,变化的只是在前后端的分配关系。而且很有趣的是,web开发的风格和餐饮风格的发展也很一致。
你看现在开的最多的火锅店和烤肉店,其实就是重前端轻后端的模式,后端提供的素材粒度非常细,并且加工程度非常低,你就不得不搞一个锅\炉子\Model 层来处理它们了。
到底,不用 Model还是旧前端延续下来的习惯。
“我们不用搞”(后台写好前端只需要修改样式 不关注其他)
“拉下来直接能用”(现在 js 直接使用json与View交互)
“拉下来改改就能用”(RESTful Api 格式 前端需要对颗粒化的数据进行处理)
“多套两个回调搞的定”(RESTful Api 格式 前端需要对颗粒化的数据进行处理)
“后端,你们给我开个新的接口...”(GraphQL 所有复杂的业务都放在前端,传说中的后台只需要开接口 SQL语句前端来写)
而用 Model 的理由通常只有一个
"懒得跟你这些后端 BB 了,老子自己写..."
当然,随着现在前端越来越重,作为一个有责任心和有追求的前端,建立良好的前端数据管理模型是很有必要的。
为什么之前JS的开发同事不使用Model
1.JS比较注重使用的灵活性,尽量不对数据进行约束,因为是动态类型,一切设计模式都可以不用,想怎么玩儿就怎么玩儿,怎么短平快怎么玩儿。(我把“TypeScript”删了我任性)
2.换成 JS 这种动态语言一路点点点,点过去毫无障碍(不使用说“懒”,使用完“真香”o(´^`)o)
3.点两下的成本比定义 model 低太多,而且 model 定义完了,没有编译器就没有立等可见的检查,回报不立即见效(说白了就是编辑器不还用)
4.静态界面,业务逻辑简单。(当我没说)
使用model好处
1.使View层与Api借口隔离,View的显示不在依赖于借口返回的字段
2.方便加入数据过滤,保证数据安全。
3.提供了一个你可以为所欲为的统一地带。(你可以对接口返回的信息处理完以后,在显示在界面上)
4.代码可读性强,写代码不用猜(不是什么时候都要去翻接口文档,也不用左边接口文档 右边开发了 (▽))
5.接口或者字段修改会有错误提示信息(妈妈再也不担心我漏改了)
6.重构的时候比较方便
使用model缺点
会加大代码量,增加开发时间
使用场景介绍
1.返回的数据需要进行处理
放回数据格式为
{
group: [
{
"A": [
{
"name": "...A",
}
],
}
]
}
但是我显示的时候分组值没有用的 我显示的时候其实只需要这种格式就好了
{
"A": [
{
"name": "...A",
}
],
}
这中情况我们可以在A生成的Model里面添加一个方法 Model的group进行处理 返回我需要的显示对象
2.数据过滤场景
需要提交的数据和显示的数据并不一致,显示的数据多个几个自定义的字段
非model情况:需要单独对数据进行删除,然后在提交
使用model情况:在生成的model里面是有两个对应的方法的
TestFromJson(NewChargeEntity data, Map<String, dynamic> json) {
if (json['A'] != null) {
data.A= json['A']?.toString();
}
if (json['B'] != null) {
data.B= json['B']?.toString();
}
if (json['C'] != null) {
data.C= json['C']?.toString();
}
}
return data;
}
Map<String, dynamic> TestToJson(NewChargeEntity entity) {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['A'] = entity.A;
data['B'] = entity.B;
return data;
}
一个是对应的json转model,一个是对应的model转json提交的时候我们主需要把需要过滤掉的C元素删除即可
3.关于重构
由于计算原因需要吧原来的一个字段有String改为num
非model情况:需要在原来所有显示的地方都改为.toString
使用model情况:重写get方法返回String类型即可(还可以设置保留位数)
4.关于安全性
在使用过程中:我们认为后台返回的接口是“不可信任的”(因为有时候修改没有同步),使用model可以在后台和前台产生一个映射,可以对后台返回的数据格式做一定的限制,这样我们可以在后台修改数据类型没有进行通知的情况下抛出一个异常,进行统一处理
推荐使用
image.pngIDE插件 vscode没有 我也不知道为什么
使用方式
1.点击新建
image.pngimage.png
2.点击make生成类
生成的可显示的类
class NewChargeEntity with JsonConvert<NewChargeEntity> {
String id;
String name;
String test;
}
同时会生成一个Help的类用于解析Model和Model转json
helper类
newChargeItemEntityFromJson(NewChargeItemEntity data, Map<String, dynamic> json) {
if (json['id'] != null) {
data.id= json['id']?.String();
}
if (json['name'] != null) {
data.name= json['name']?.String();
}
if (json['startRow'] != null) {
data.test= json['test']?.String();
}
return data;
}
Map<String, dynamic> newChargeItemEntityToJson(NewChargeItemEntity entity) {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = entity.id;
data['name'] = entity.name;
data['test'] = entity.test;
return data;
}
3.生成后修改或者添加字段 如 后台修改id为mid 并添加一个新字段sid 我们只需要添加注解 然后alt+l就可以了
class NewChargeEntity with JsonConvert<NewChargeEntity> {
@JSONField(name:"mid")
String id;
String name;
String test;
@JSONField(name:"sid")
String sid;
}
添加完成后点击
image.png
就会重新构建Helper类 并修改字段
4.添加业务字段isChecked判断是否选中并不用来传输 添加注解 deserialize(默认true)是否参与fromJson解析,serialize(默认true)是否参与tojson,
class NewChargeEntity with JsonConvert<NewChargeEntity> {
String id;
String name;
String test;
@JSONField(name:"mid",serialize: false,deserialize: false)
bool isChecked;
}
}
网友评论