【JQuery】扩展 $.val()

一、背景

公司的老项目前端还是用的jquery,也没有条件引入vue,所以对于一个实体对象的取值和赋值还是很麻烦的:
例如:

image.png

所以想扩展一下$.val()函数

二、目标

html元素上使用name结构化数据实体,
然后用val获取整个实体,可以正确处理子对象和数组对象以及多选select
例如:

三、修改方案

找到$().val的源码;
会用jquery的同学都很清楚,val有2个逻辑,不带参是get,带参是set
看源码,有一个JQuery.valHooks 对象,如果当前元素可以匹配到则会直接调用valHooks中定义好的getset方法;
所以只要在这里加入我们定义好的元素和处理函数就可以了

四、改造Get

先来改造Get



将希望处理的元素全部加进去:


五、改造Set

set方法有一个比较有意思的地方,在数组的操作中,每次都要能取出数组中的下一个元素,有点类似C#中的IEnumerator
使用时,需要将数组转为 Enumerator 再调用 .next() 方法来获取下一个值;
PS:这里有个特殊情况是 <select multiple>是可以直接用数组赋值的

function Enumerator(array) {
    if (array == null) {
        return;
    }
    let index = 0;
    this.next = function () {
        if (index >= array.length) {
            index = 0;
        }
        return array[index++];
    };
    this.all = function () {
        return array;
    };
}
// ...
let val = model[name];
if ($.isArray(val)) {
    val = model[name] = new Enumerator(val);
}
if (val instanceof Enumerator) {
    if (jq.is("select[multiple]")) {
        jq.val(val.all());
    } else {
        jq.val(val.next());
    }
}

但是这样做会改变model对象中的值,所以需要先将model对象拷贝出来使用

function Copied(value) { Object.assign(this, value); }
// ...
const copied = model instanceof Copied ? value : Copied(value);

完整set代码


demo

扩展JQuery.val demo - JSRUN

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Chapter 2 : Selecting the elements upon which to act 1. $...
    Azur_wxj阅读 413评论 0 1
  • 一:认识jquery jquery是javascript的类库,具有轻量级,完善的文档,丰富的插件支持,完善的Aj...
    xuguibin阅读 1,727评论 1 7
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,203评论 0 1
  • Map和Set --是ES6新增的两个数据类型 --都属于内置构造函数 既 使用new的方法来实例化 Set是一个...
    小胖子_d7d8阅读 164评论 0 0
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,394评论 0 2