[easyui]总结一下目前项目里遇到的小麻烦

数据字典

比如我们将用户性别存入数据库,一般都是用数字来存储,比如1表示男性,2表示女性。

这时候碰到这样一个需求,
一个datagrid需要支持行编辑,
然后性别这一列用combobox来做。

那如何方便的在前台将数据 1 显示成对应的 ‘男’ 呢?


首先要先定义好这个列

{
    field:'gender',title:'性别',width:80,
    editor:{
        type:'combobox',
        options:{
            // 1种做法是通过url获取数据,有个弊端后面说明
            url:'fetchGender',
            // 还有一种做法是直接赋值data,这里的值跟上面的url返回相同。
            data:[
                {value:'1',text:'男'},
                {value:'2',text:'女'},
            ]
        }
    }
}

我们再来看看数据接口应该返回什么样的数据

心急的人会选择直接将要显示的值返回过来

[
    {"name":"关羽","gender":'女'},
    {"name":"张飞","gender":'男'},
    {"name":"马超","gender":'男'},
    {"name":"黄忠","gender":'女'},
    {"name":"赵云","gender":'男'}
]

这里写图片描述

这么一看没什么问题啊,但如果你进行编辑的话,随便选了一个值之后保存该数据,就会看到
这里写图片描述

所以这个列还是老老实实的返回value值


那问题又来了,怎么能显示对应的text值?

我见过很多人是这样做的

接口数据:

[
    {"name":"关羽","gender":2,"displayGender":"女"},
    {"name":"张飞","gender":1,"displayGender":"男"},
    {"name":"马超","gender":1,"displayGender":"男"},
    {"name":"黄忠","gender":2,"displayGender":"女"},
    {"name":"赵云","gender":1,"displayGender":"男"}
]

多返回了一个数据,然后在列上加上这样一个formatter

{
    field:'gender',
    ...
    formatter:function(value,row,index){
        return row.displayGender;
    }
}

这样确实也能正常显示
这里写图片描述
但是!
你会发现,还是编辑出了问题,因为你无论怎么改,数据都还是显示一样的值。
因为虽然编辑的时候改变了当前gender的值,但是displayGender的值并没有同步更改,所以始终显示为初始值。

所以要想实现功能,还需要在结束编辑的时候,同步更新 displayGender 的值。
大概流程是这样

取到当前正在编辑行的性别列的combobox组件
取到text值
先 endEdit 结束行编辑
再 updateRow 更新当前行的 displayGender 值

这种做法,首先是数据接口会多返回一列数据,这对于追求完美的我来说是不允许的。
同时操作也不够优美,就感觉太拐弯了。


现在,分析一下思路。

我们知道这个列所有可能的值(通过接口可以拿到数据),
那我们就可以在formatter里面去遍历找到对应的text用来显示。

为此,我封装了一段代码。

function FieldData(data, _v, _t) {
    // 标识是否已获取过数据
    var isGet = true;
    // 支持自定义字段的名字
    var valueField = _v || 'value', textField = _t || 'text';
    // 数据,如果为字符串表示需要从后台获取的。
    var _data = data;
    if ('string' === typeof data) {
        isGet = false;
    }

    // 获取数据
    function get() {
        if (!isGet) {
            $.ajax(data, {
                dataType: 'json',
                async: false,
                success: function (data) {
                    _data = data;
                    isGet = true;
                }
            });
        }
        return _data;
    }
    return {
        getData: function () {
            return get();
        },
        formatter: function (value, row, index) {
            var data = get();
            for (var i = 0, len = data.length; i < len; i++) {
                var item = data[i];
                if (item[valueField] == value) { return item[textField] }
            }
            return value;
        }
    };
}

说下用法

// 声明一个字段
// 有三个参数,
// 第一个参数 可以为 String,Array,如果是String就代表url,如果是Array就表示直接将数据定义好了。
// 后面两个参数 valueField,textField,都是可以省略的,如果接口返回的数据不是 {value:'',text:''} 这样,那就得声明好
var fieldGender = new FieldData('/api/fetchGender');

// 也可以这样用
fieldGender = new FieldData([
    {id:1,name:'男'},{id:2,name:'女'}
],'id','name');

对了,如果是通过url定义的数据,在获取数据的时候,是设置的同步获取的,这样代码好控制一点。而且用的是get方式,如果需要post方式请自行修改。

现在 fieldGender 有两个方法

  • getData (获取数据并将数据进行缓存)
  • formatter

然后我们重新定义列

{
    field:'gender',
    ...
    editor:{
        type:'combobox',
        options:{
            // 这里就不用设置url了,而且也不推荐用url
            // 因为如果使用url的话,每次进行编辑的时候,都会请求一次。
            data:fieldGender.getData()
        }           
    },
    // 直接将字段的方法放到这边来即可
    formatter:fieldGender.formatter
}

现在一切正常了。

接口数据:

[
    {"name":"关羽","gender":2},
    {"name":"张飞","gender":1},
    {"name":"马超","gender":1},
    {"name":"黄忠","gender":2},
    {"name":"赵云","gender":1}
]

初始显示:
这里写图片描述
修改一条数据:
这里写图片描述
完成编辑:
这里写图片描述

花了一下午把这篇写完,本来不打算配图的,但觉得有图看着就很直观。


更新日期:2016年3月15日17:57:16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值