Ruby's Louvre

每天学习一点点算法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

利用avalon 实现一个简单的成绩单

本文的灵感是来自Halower的这篇博文,他是使用knockout与jQuery实现的。不过我觉得MVVM本来就强大的事件绑定功能,因此用jQuery 是多此一举。另,他也用了一些面向对象的写法。我个人认为,纯数据就该好好当纯数据,作为数据模型(M)而存在,想操作数据,则交由视图模型(VM)。在angularjs流行的一些成规,都是要求大家不要自己操作DOM,DOM是框架自行帮你偷偷搞定。这也与avalon一直提倡的“操作数据即操作DOM”的理念相符。由于avalon巧妙地利用了Object.defineProperty, __defineSetter__, __defineGetter__, VBScript等方法把等于号(=)重载了,因此与视图的同步就变得比其他MVVM更隐秘神奇。那么接着下来,让我们看看avalon是如何实现这个功能吧。

首先是视图层,里面的绑定属性其实可以在VM中的属性定了下来再添加。这也涉及MVVM另一个优势,分离关注点,因此切图与JS编程可以同时进行。由于JS代码不进行DOM操作,页面长得怎么样也无所谓,我又不需要选择器引擎!

<div ms-controller="grid" class="grid" >
    <div>
        <p> <input ms-duplex="id">
            <input ms-duplex="name">
            <input ms-duplex="score" data-duplex-event="change"></p>
        <p><button ms-click="add"> add</button></p>
    </div>
    <p>共{{array.size()}}条------------------合计{{total}}分</p>
    <table>
        <thead>
            <tr>
                <th>ID</th> <th>姓名</th> <th>分数</th> <th>操作</th>
            </tr>
        </thead>
       
        <tbody ms-each-el="array">
            <tr>
                <td>{{el.id}}</td>
                <td>{{el.name}}</td>
                <td>{{el.score}}</td>
                <td align="center"><a ms-click="$remove" href="javascript:void(0)">移除</a></td>
            </tr>
        </tbody>
    </table>
    <textarea ms-value="JSON.stringify(array.$model)" style="width:90%;height:220px;"></textarea>
</div>

样式随便弄弄:

.grid table{
    border:1px solid #000;
    width:500px;
    border-collapse: collapse;
}
.grid button{
    width:400px;
    background: orange;
}
.grid table th, .grid table td{
    border:1px solid #000;
    padding: 2px 5px;
}

从HTML结构来看,分为两部分,一个是用于输入数据,另一个是呈现所有数据,数据上方还有个小统计。输入数据部分有三个输入项,我们对分数中进行校验,只保证其是数字就行了,目的是为了相加,因为input的value属性总为一个字符串类型。下方有个按钮,用于提交。呈现区为一个table,所有MVVM框架都支持数组循环输出,我的与angular走得很近。在循环区域,里面还内置一个$remove方法,用于删除监控数组中的某一个元素,这个比knockout人性化多了。下面是JS部分,你是看不到一句操作DOM的代码。

//如果大家对avalon不熟悉,可以参看这篇入门教程 http://www.cnblogs.com/rubylouvre/p/3181291.html
            avalon.ready(function() {
                var model = avalon.define('grid', function(vm) {
                    vm.id = ""
                    vm.name = ""
                    vm.score = 0
                    vm.total = 0
 
                    vm.add = function() {
                       if(vm.id && vm.name ){
                           vm.array.push({
                              id: vm.id,
                              name: vm.name,
                              score: vm.score
                           })
                       }
                    }
                    vm.array = []          
               });
 
                model.$watch("score", function(a) {
                        var a = Number(a) || 0
                        a = a > 100 ?  100 : a < 0 ? 0 : a//强制转换为0~100间
                        model.score = a
                })
                model.array.$watch("length", function() {
                    var a = 0
                    model.array.forEach(function(el) {
                        a += el.score//求得总数
                    })
                    model.total = a;
                    model.id = ""
                    model.name = ""
                    model.score = 0
                })
                model.array = [
                    {id: "d1", name: "李世民", score: 67},
                    {id: "d2", name: "赢政", score: 90}
                ]
 
                avalon.scan();
            });

我们在define方法中定义了VM所有用到的数据,什么id, name, score, array, 还有需要绑到视图中的add方法。数据校验或数据变动时需要做的操作,我们是用$watch实现,它们被安排到define方法外,这是一个好主意。然后,就没有然后了!这就是MVVM的神奇之处,因为我们在视图中使用了{{}}, ms-click已经指明了它们的行为。因此当数据变动时,框架自然明白自己该什么做。

共2条------------------合计157分

ID 姓名 分数 操作
d1 李世民 67 移除
d2 赢政 90 移除

目前我与5群的一些人已经将avalon应用于公司的生产环境,反应还是不错。虽然目前还不时冒出一些怪异的BUG,但难度不至于影响我们的进度,基本上半天就能修,比如说IE9-10的option标签的value问题,firefox 全系列下,未插入DOM树的元素的display样式取值问题,这是jQuery也没报到的新东西。有的话,我在做mass Framework时已经遇到过了。MVVM是一个全新的领域,要求对用户全面隐藏DOM操作,并将整个DOM树作为一个动态模板或数个复用的子模板,另外,DOM树其实也被我框架看作为一个Ioc容器的配置文件。如此种种,遭遇新的问题在所难免,但只要方向是对的,这就是康庄大道。虽然它与jQuery走的是一条截然不同的路,但明显优于jQuery。jQuery与DOM存在强依赖,导致维护成本奇高。这正是西方继jQuery后,又孜孜不倦发明backbone, canjs, knockout, emberjs, angular的原因。现在国内的技术步伐普通比外国慢两三年,现在前端MVVM已经在外国非常盛行,希望国人不要再落后太多了。

如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码

posted on   司徒正美  阅读(10848)  评论(12编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2012-07-25 Node.js : exports と module.exports の違い
2012-07-25 node.js Domain 時代のエラー処理のコーディングパターン
2011-07-25 mass Framework class模块 v5
点击右上角即可分享
微信分享提示