23、ms-duplex 2.0
发布在avalon学习教程2014年11月12日view:18903
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

一直以来,avalon从VM同步到V是非常强势,几乎所有指令都参与到此事件上来;而从V到VM则非常软弱,就只有ms-duplex在单打独斗,并且它是直接将element.value同步到VM,没经过什么加工,最多是将字符串变成字符串数组,没有更多的数据类型。假如我们某个VM属性是数字,同步到V就变成字符串,而从V搞回到VM,还是字符串,这个非常不友好。

在avalon1.3.5中,我们添加了一个ms-duplex-bool稍微打破了这局面,允许radio的值强制转为布尔。

但ms-duplex及其一些衍生品,ms-duplex-textms-duplex-boolms-duplex-radio,其实是挺混乱,它们都是迫于业务线的压力,慌乱诞生的,没有经过统一的规划,科学的设计,也不易记住其用法及其应用对象。它们统称为ms-duplex 1.0

在avalon1.3.6中,低调引入ms-duplex-stringms-duplex-numberms-duplex-booleanms-duplex-checked取代原来的ms-duplex-textms-duplex-boolms-duplex-radio,统称为ms-duplex 2.0

旧有的ms-duplex家族与新的ms-duplex家族对比如下:

<col width="190"> <col width="220">
功能
ms-duplex-checked
只能应用于radio、 checkbox
ms-duplex
只能应用于radio
ms-duplex-radio
checkbox
通过checked属性同步VM
ms-duplex-string
应用于所有表单元素
ms-duplex-text
只能应用于radio
通过value属性同步VM
ms-duplex-boolean
应用于所有表单元素
ms-duplex-bool
只能应用于radio
value为”true”时转为true,其他值转为false同步VM
ms-duplex-number
应用于表单元素
没有对应项 如果value是数字格式就转换为数值,否则不做转换,然后再同步VM
ms-duplex
相当于ms-duplex-string
ms-duplex
在radio相当于ms-duplex-checked
在其他上相当于ms-duplex-string
见上

在avalon1.3.7中,添加了avalon.duplexHooks钩子对象, 什么ms-duplex-boolean都可以在它上面找到实现:

    function fixNull(val) {
        return val == null ? "" : val
    }
    avalon.duplexHooks = {
        checked: {
            get: function(val, data) {
                return !data.element.oldValue
            }
        },
        string: {
            get: function(val) {//同步到VM
                return val
            },
            set: fixNull
        },
        "boolean": {
            get: function(val) {
                return val === "true"
            },
            set: fixNull
        },
        number: {
            get: function(val) {
                return isFinite(val) ? parseFloat(val) || 0 : val
            },
            set: fixNull
        }
    }

此外还有一个pipe内部方法,允许我们在ms-duplex-后面接N个单词,每个单词对应avalon.duplexHooks中一个对象,我们称之为拦截器

    function pipe(val, data, action, e) {
        data.param.replace(rword, function(name) {
            var hook = avalon.duplexHooks[name]
            if (hook && typeof hook[action] === "function") {
                val = hook[action](val, data)
            }
        })
        return val
    }

有了拦截器机制,我们就可以用ms-duplex做更多的事情,如格式化处理数据验证,带来N多兄弟,ms-duplex-maskms-duplex-intms-duplex-chsms-duplex-email ms-duplex-urlms-duplex-id……用户缺什么就在duplexHooks造什么,制定性非常强大!

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="avalon.js" ></script>
        <script>
            var model = avalon.define({
                $id: "test",
                a: true,
                b: true,
                c: "",
                d: "",
                e: 10,
                f: true,
                g: ["b", "c"],
                h: [1, 4],
                i: [false],
                j: "2222",
                k: 2222,
                l: false,
                m: ["bbbb","dddd"],
                n: [11,44],
            });
            model.$watch("$all", function(a, b) {
                if (!/^avalon\-/.test(a)) {
                    avalon.log([a, b, typeof b].join("   "))
                }
            })
            model.g.$watch("length", function() {
                avalon.log(model.g)
            })
            model.h.$watch("length", function() {
                avalon.log(model.h)
            })
            model.i.$watch("length", function() {
                avalon.log(model.i)
            })
              model.m.$watch("length", function() {
                avalon.log(model.m)
            })
              model.n.$watch("length", function() {
                avalon.log(model.n)
            })
        </script>
    </head>
    <body>
        <div ms-controller="test">
            <h3 style="text-align: center">ms-duplex</h3>
            <table>
                <tr>
                    <td>
                        <p>ms-duplex-checked<input ms-duplex-checked="a" type="radio" />{{a}}</p>
                        <p>ms-duplex-checked<input ms-duplex-checked="b" type="checkbox"/>{{b}}</p>
                        <p>ms-duplex-string<input ms-duplex="c" />{{c}}</p>
                        <p>ms-duplex-string<input ms-duplex-string="d" />{{d}}</p>
                        <p>ms-duplex-number<input ms-duplex-number="e" />{{e}}</p>
                        <p>ms-duplex-boolean<input ms-duplex-boolean="f" data-duplex-event="change" />{{f}}</p>
                    </td>
                    <td>
                        <p>ms-duplex-string
                            <input ms-duplex-string="g" type="checkbox" value="a" />
                            <input ms-duplex-string="g" type="checkbox" value="b" />
                            <input ms-duplex-string="g" type="checkbox" value="c" />
                            <input ms-duplex-string="g" type="checkbox" value="d" />
                            {{g}}</p>
                        <p>ms-duplex-number
                            <input ms-duplex-number="h" type="checkbox" value="1" />
                            <input ms-duplex-number="h" type="checkbox" value="2" />
                            <input ms-duplex-number="h" type="checkbox" value="3" />
                            <input ms-duplex-number="h" type="checkbox" value="4" />
                            {{h}}</p>
                        <p>ms-duplex-boolean
                            <input ms-duplex-boolean="i" type="checkbox" value="false" />
                            <input ms-duplex-boolean="i" type="checkbox" value="true" />
                            {{i}}</p>
                        <p>ms-duplex-string/ms-duplex
                            <select ms-duplex="j">
                                <option>1111</option>
                                <option>2222</option>
                                <option>3333</option>
                            </select>
                        </p>
                        <p>ms-duplex-number
                            <select ms-duplex-number="k">
                                <option>1111</option>
                                <option>2222</option>
                                <option>3333</option>
                            </select>
                        </p>
                        <p>ms-duplex-boolean
                            <select ms-duplex-boolean="l">
                                <option>true</option>
                                <option>false</option>
                            </select>
                        </p>
                    </td>
                    <td>
                        <p>ms-duplex-string/ms-duplex<br/>
                            <select ms-duplex="m" multiple>
                                <option>aaaa</option>
                                <option>bbbb</option>
                                <option>cccc</option>
                                <option>dddd</option>
                            </select>
                        </p>
                        <p>ms-duplex-number<br/>
                            <select ms-duplex-number="n" multiple>
                                <option>11</option>
                                <option>22</option>
                                <option>33</option>
                                <option>44</option>
                            </select>
                        </p>
                    </td>
                </tr>
            </table>
        </div>
    </body>
</html>

enter image description here

评论
发表评论
3年前
赞了此文章!
3年前

@coolText 我也想问,你解决出来了吗?

3年前

“radio控件不能同时定义ms-attr-value与ms-duplex-string” 求解释~

3年前
赞了此文章!
3年前
赞了此文章!
3年前

列表页,鼠标三维效果 IE 11 不兼容!

4年前

这个好,终于不用再另建一个辅助的属性了

4年前

@coolText 用jquery

4年前

怎么读取Web服务器上的json数据?

WRITTEN BY
司徒正美
穿梭于二次元与二进制间的魔法师( ̄(工) ̄) 凸ส้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้
TA的新浪微博
PUBLISHED IN
avalon学习教程

从零开始学习到掌握当前国内最强大的MVVM框架avalon

我的收藏