`

avalon如何在兼容ie的情况下做到双向绑定呢?

 
阅读更多
avalon可以兼容到ie6,貌似它的双向绑定是和vue一样用object的set和get实现的,那是如何实现兼容呢?还有一个问题,angular用了许多object对象的方法才不兼容ie的么,那么angular当初为什么不做兼容呢?脏检查机制完全可以做到兼容。或者说有什么技术使ng很难兼容呢?

 

 
 
司徒正美
JavaScript 话题的优秀回答者
112 人赞同了该回答

avalon兼容IE6其实没有你们想象的那么困难,主要是知识面上的差异。

像我掌握js, ruby, python, vbscript等多种脚本语言的前提下,一些认为非夷所思的思路其实对我来说也不是什么大事。

退一步说,avalon的各个版本实现双向绑定也不尽然。

avalon1.4.*与1.5.*是使用动态收集依赖,这是从knockout那里学来的。

js语句针对于 = 号,有两种用法

赋值语句, obj.a = 1

取值语句,var b = obj.a

我要做的是就是劫持了这个等号,让它在取值时进行依赖收集,赋值时进行视图更新。这在其他语言中,有settter,getter可用,而在前端,只有IE8只以用set,get语句,Object.defineProperty只能用于元素节点。只有到了IE9及其他高版本W3C浏览器,这个Object.defineProperty才能让我大胆使用。幸好的是,W3C浏览器早就有__defineSetter__,defineGetter__可用。

问题就是IE6-8,我稍微动用了VBScript。 用到VBScript的代码也不超过100行。当然这对于不懂VBScript的人可能是很难的。因此博学是有好处,能拓展你的思维与门路。

其他要兼容IE的处理,比较事件绑定要用attachEvent, dettachEvent啊,监听元素的value值变化要用propertychange事件啊,IE的NodeList不能用Array.property.slice.call来转化啊,这些都有现成方案,兼容起来一点难度也没有,并且合起来也不超过500行代码。

在avalon1.5,我还学习angular那样使用静态分析进行依赖收集,到avalon1.6这个技术已经研习得差不多,到avalon2,由于大量使用虚拟DOM技术与单纯的静态分析依赖,vm就更加轻量,源码里也很少操作DOM了。

只要不怎么操作DOM,针对IE的hack也用得很少,反而,为了性能,avalon是动用了大量的新API,这些HTML5 API所占比例是其他MVVM框架无法比拟的。

因此不要总盯着avalon兼容IE6 的方面,就算是兼容了IE6,avalon1.4.7.2的5893行代码,也比小而美的vue的9820行代码, angular的30248行代码, 只专注视图的react的2W行代码(此外你通常还要加上1W5K行的JSX转换器, redux才能用于生产环境) ,emberjs的5W8K行代码, 精简多了!
 
貘吃馍香
北京碎催,胡同串子,说话痞,圣母婊请勿近
15 人赞同了该回答

路过
刚好之前跟教主扯淡时候说过这个
并写了个大致例子
现成可用不费脑子就来答下

主要是用 Object.defineProperty 就可以搞了
但是对于老版本 IE 这玩意没有
就用VBS来搞了
(这是听正美说的,他的 avalon 我没看过也没用过……)
基本上老的快入土前端的估计到这就明白了

原理很简单
VBS 的 Class 中成员对象可以 Get 和 Set
VBS 的变量值在老 IE 中又可以和 JScript 互通
所以应该是用 VBS 构建 Class 并实例化返回结果就好
而且 IE 的 execScript 函数可以根据语言类型动态运行 code
就能做到动态构建 VBS 代码执行并拿到返回结果
核心原理大致如下:
var code = '' +
'Class MyObject\n' + 
'       Private px \n' + 

'       Sub Class_Initialize()\n' + 
'       px = 1\n' + 
'       End Sub\n' + 

'       Public Property Get x\n' + 
'       alert("Get Value is:" & px)\n' + 
'       End Property\n' + 

'       Public Property Let x(nx)\n' + 
'       alert("Set Value is:" & nx)\n' + 
'       px = nx\n' + 
'       End Property\n' +  

'End Class\n' + 

'Dim obj\n' + 
'Set obj = New MyObject';
execScript(code, 'vbscript');
obj.x;
obj.x = 2;

此时 JS 的 obj 对象成员 x
在 set get 时候都可以有 alert hook 的调用

当然
angular 没跟 avalon 一样这么搞是因为
它们压根没有兼容老 IE 的需求
毕竟国外市场IE6这等老古董早就入土了
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics