精华 项目需要造了个轮子,轻量级双向数据绑定工具 modelite.js
发布于 9 年前 作者 kankungyip 8413 次浏览 最后一次编辑是 8 年前 来自 分享

modelite.js

轻量级双向数据绑定工具。

https://github.com/kankungyip/modelite.js

特点

  1. 简单
  2. 轻量
  3. 持久

安装

<script src="modelite.min.js"></script>

* 需要 jQuery 库。

快速入门

无需编写任何代码,将 DOM 元素的 name 属性和数据名对应,就可以完成绑定。 DOM 的层次关系也就是数据对象的层次。

    <form name="data">
        <input type="text" name="name">
        <input type="text" name="age">
        <input type="text" name="gender">
    </form>

    Name: <span name="data.name"></span>

在内存中储存的数据为:

{
    "data": {
        "name": "",
        "age": "",
        "gender": ""
    }
}

选项属性

对 DOM 元素使用以下 ml- 属性可以实现对数据的简单操作和显示控制。

属性 类型 默认值 说明
default String null 数据的默认值。
placeholder String null 数据为空值时标签元素上可以显示的值,该值不储存。
reserve Number 0 对于 Array 类型的数据,必须保留的数据数量,不足时用默认值填充。
repeat String all 循环模版标签元素时,控制模版显示的方式,可选择值:headerfooterbodyoddevenall,,使用详见后文。
insert String null 插入动作,往 Array 中插入新数据,使用详见后文。
remove String null 删除动作,删除 Array 中的数据,使用详见后文。
events String null 触发的事件,使用详见后文。

实例:

    <span name="name" ml-default="Kan"></span>
    <img name="avatar" ml-placeholder="https://avatars1.githubusercontent.com/u/1096425">
    <button ml-remove="list.0"></button>

循环

将 DOM 元素(及其子元素)指定为模版,绑定的 Array 类型数据的每一个值都会用该模版显示出来。 指定为模版的 DOM 元素只需要用 # 作为 name 属性的值,并且将该元素包裹在绑定对应 Array 类型数据的父元素内。

    <div name="people">
        <p name="#">
            <span name="name"></span>
            <span name="age"></span>
        </p>
    </div>

在内存中储存的数据为:

{
    "people": [
        {
            "name": "",
            "age": ""
        }
    ]
}

如果模版子元素的 name 属性值为 $,则可以用来表示直接将使用数组元素的值。

    <div name="people">
        <div name="#">
            <p name="$"></p>
        </div>
    </div>

循环选项

通过 ml-reserveml-repeat 两个选项来控制数据显示的方式。

如果需要在显示时候指少保留 n 个默认项,则使用 ml-reserve="n" 来设置保留项的个数。ml-reserve 必须在循环的父元素属性中设置。

    <select name="list" ml-reserve="1">
        <option name="#"></option>
    </select>

如果要控制模版在循环时特定时候显示或隐藏,则使用 ml-repeat="header|footer|body|odd|even|all" 来控制只在设定的状态下才显示。

  • header 循环第一次显示
  • footer 循环最后一次显示
  • body 非循环的第一次或最后一次显示
  • odd 奇数次循环显示
  • even 偶数次循环显示
  • all 默认值,始终显示。
    <div name="people">
        <div name="#">
            <p ml-repeat="header">Name: Age</p>
            <p>
                <span name="name"></span>:
                <span name="age"></span>
            </p>
            <p ml-repeat="footer">End</p>
        </div>
    </div>

动作

依据循环的模版对绑定的 Array 类型数据执行插入(ml-insert)和删除(ml-remove)操作,新插入的值均使用模版中定义的默认数据。

插入和删除动作的属性值为绑定数据的 keypath,如果 keypath 中不包含 index,则默认为最后一项。

    <select name="list">
        <option name="#" ml-default="0"></option>
    </select>
    <button ml-insert="list">Add</button>
    <button ml-insert="list.0">Remove</button>

如果 keypath 中包含 #,则会自动替换成当前模版的 index (使用在模版的子元素上才有效)。

    <div name="people">
        <p name="#">
            <span name="name"></span>
            <span name="age"></span>
            <button ml-remove="people.#">Delete</button>
        </p>
    </div>

APIs

ml(keypath [,value])

获取或设置绑定的 keypath 数据的 value

ml.clear(keypath)

清除绑定的 keypath 数据。

ml.insert(keypath, value)

向绑定的 Array 类型的 keypath 数据插入新 valuekeypath 中如果没有指定 index 则默认插入到最后一个元素。

ml.remove(keypath)

从绑定的 Array 类型的 keypath 数据删除一个元素,keypath 中如果没有指定 index 则默认删除最后一个元素。

ml.emit(keypath, eventType)

通过绑定数据的 keypath 查询 DOM 元素,然后手动触发 eventType 类型事件。

ml.emit(eventName [,eventArgs...])

手动触发 eventName 事件,并且传递事件参数表 eventArgs...


The MIT License (MIT)

Copyright © 2015 Kan Kung-Yip

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

6 回复

这样的双向绑定看起来有点意思,看代码也足够轻量。 不知道对于同name的情况是怎么处理的?

挺好的,类似angular,vue都一样

@zsxsoft 同name的只要不是在同一个节点下就是不同的数据,否则就是同一个 自豪地采用 CNodeJS ionic

@kankungyip 在项目中是经常用到name="name[]"这样的形式传给后端的……这样PHP就可以直接将其作为数组处理

指令前缀名不错!

回到顶部