备注: uee是我厂内部的一个前端框架.

这可能是最后一篇关于uee的文章了,因为已经不关注这个方面的技术很久了。术业有专攻,前端嘛,那可怕的前端摩尔定律,还是让专业人士去操心吧。

上个星期有一天,有同事反馈uee的watch不好使,变量已经修改,但watch回调方法不走进去。今天主要围绕这些类似的问题展开,不过呢,今天不对具体问题进行解析,今天主要讲讲uee的黑魔法,大道至简嘛,抽象(原理)和具体(使用)得两手抓,两手都要硬。

下面的内容,主要针对非专业前端(从其他领域过来的开发人员),或者对uee有兴趣的同事。专业人士请绕路。

先进行术语简介。ng1代表angular1.x版本,ng2代表angular2.x以上版本。

uee的本质是ng1

uee是一个前端mvvm框架,常用于SPA(single page application)的开发,虽然开发指南上没有明目张胆的宣传,但底层是ng1是事实,所以ng1.x的文档总是可以借鉴的,网上找到的关于ng1的吐槽也同样适用。关于什么是MVVM,参考阮大的博客http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html

ng1和ng2的区别,和雷锋、雷峰塔的区别差不多,外边新项目考虑ng的话,只会考虑ng2之后的版本。uee后来有个ts(typescript)版本,写法上高仿了ng2的写法,不过这里不关注。

ng1的核心概念比较多,DI,scope,双向绑定,指令,digest都是比较重要的,还是那句话,即使使用uee,熟悉ng1的核心概念没有任何坏处。

关于开发模式

这部分主要针对从传统MVC过来的童鞋,因为开发习惯的原因,总是会考虑操作页面,例如某个操作要让按钮高亮,有同学就可能贪方便直接操作style,但这不是正确的做法。mvvm关注的是数据的管理,界面的变化(dom)是自动的。习惯不纠正,写出来的代码可能很诡异。参考文章http://www.infoq.com/cn/news/2013/11/how-to-think-angularjs

变化来自watch

框架的第一印象就是一个页面上一个占位符,只要对应的变量发生变化,页面就会自动变化。这个特性是非常自然的,直到有一天你需要使用watch来监控一些变量,并在发生变化的时候做些什么。

其实,页面变化的魔法也是使用watch机制。所以某个页面上可能会生成非常多watch表达式。这个就是单向绑定的内容了。

例如下面的例子

<div>\{\{content\}\}</div>,就是会生成类似watch("content", function(){//修改div内容})的逻辑。

变化如何被感知 digest过程

现在页面有这么多watch,怎么鉴别有发生变化了?

客户端js是单线程执行的,所以不能写个死循环。可以想象到的做法有2种,一种就是死循环加个timeout或者interval,一种是被动触发。ng1是采用被动触发的,只是就是一些特殊的页面事件会导致检查的发生,这个检查的过程叫digest,俗称dirty check 脏检查。

主要的事件有,页面初始化,页面发生操作(例如点击,输入)等,至于一些异步行为,例如timeout,ajax等,正常是不会触发的,不过使用框架包装过的调用方式,也是会触发的。如果和其他框架例如jq插件等集成的话,或者需要确保调用到digest的话,就需要使用框架提供的apply这个功能,它会确保操作会被页面感知到,相信很多同学也见识过了。

不过,这里还有个细节: 联动更新,例如watch表达式a的时候改了表达式b,同时watch表达式b的时候又会修改a,那么页面中有一个表达式的值可能是旧的。ng1规避的做法比较简单,就是一次digest之后,发现有变更的话,再次执行一次digest,直到所有的表达式的值都稳定了,或者是超过了最大检查次数才停止。

示例伪代码如下:

watches =[] //保存所有的watch表达式和表达式的当前值
for each watch in watches //循环所有的watch表达式if watch中的变量发生变化(包括第一次初始化)记录表达式的新值执行回调,这个过程可能修改了其他变量if 没有任何表达式发生变化exit
else重新执行一遍,直到检查达到最大次数

变化没起作用的常见原因

  • 跨页面修改数据

框架的作用域顶多就是一个html页面。但如果项目有复杂的集成方式,那么就可能有多个页面并存的情况,通过a页面去更新b页面的数据变得没那么自然。首先,无论是直接修改变量还是通过所谓的emit事件通知,都有可能没生效(要等b页面下一次digest才能感知到),直接修改dom的话,则存在其他一些问题。所以规避的方式,通常的做法只能调用b页面的某个方法,而这个方法通过嵌套apply来修改变量。

  • 修改数据但没有触发digest

这种常见于采用第三方js插件,或者直接使用普通的ajax,timeout异步操作等情况,同理只能使用apply。

  • ABA问题

ABA概念可以参考知乎文https://www.zhihu.com/question/23281499
就是修改了但没看出变化,例如改了之后又改回去。这种比较特殊,ng会认为你没有变化。开头提到的那个例子,就是某种情况下,一次digest过程中出现了变量又改回原值的情况。所以确实有这种需要,就得多点信息来标记你做了修改,例如增加个时间戳的字段。

  • 变量引用发生变化

意思就是说你修改的和你显示的,已经不是同一个对象了。这个涉及js对象和scope的一些特性,可以参考https://github.com/angular/angular.js/wiki/Understanding-Scopes
这个问题曾经也出现过

谈双向绑定

前面提到了单向绑定,当然双向绑定更是一个非常神奇的特性,特别是你写了一个页面控件,想和某个变量进行绑定,可能就需要考虑了。它的实现过程是这样的: 当变量发生变化的时候,需要修改页面,很明显这个可以通过建立watch表达式实现。另一方面,页面变化的时候,需要修改变量,这个可以通过dom事件,触发包裹在apply中的变量变更操作。掌握这个基本原理的话,在需要定位自带组件问题的情况下,就会减少很多阻碍。

谈自定义gadget

gadget是uee的概念,类似于ng2的component概念,是一种页面组件,包括页面,脚本,样式的大集合。需要了解一点,凡是自定义标签,在ng1中,都采用directive特性实现,只是directive以复杂难懂著称,在使用便利性上,gadget还是做得不错的。如果有需要调试gadget或者ui component的内部实现的情况,就需要掌握指令的各种奇怪接口。

业务开发中的同步与异步

在其他项目习惯了ajax同步操作带来的开发便利性,开始使用uee的时候,可能会发现强大如fire的请求,是没办法做同步的!例如请求a以后,再请求b,这种变得比较麻烦,实现通常是这样的,一是把请求合并,只搞一次就可以了,不过说的容易,实际处理会有很多限制。一种就是在回调方法中发起下一个请求,不过这么写少量还可以,多了就存在一个callback hell的问题。所以应该考虑引入异步控制库让代码更符合人的思维,例如这个async,https://caolan.github.io/async/docs.html

我的看法

uee作为一个前端框架,使用上还是可以的,gadget表现出来的特性也是不错的。不过,也有一些毛病(可能他们觉得是特性)。

一个比较奇怪的就是webroot占位符,宣称可以表示根路径,用来引用静态资源的时候很方便,这套路好难理解,硬生生和后端绑定一起了。而且处理静态资源分离的时候,规则也没那么自然。

另外一个类似fire这种大而全的怪物,源码长达数千行,我总感觉使用fire之后MVVM的边界反而更模糊了。

还有就是,其实uee不是完全定位在纯前端的框架,还包括一个gateway来对接(虽然不是强绑定),包括了一种类似mvc的绑定风格和一种服务总线的绑定实现。说白了,绑定实现是很忌讳的事情,如果它提供一个spring mvc的实现,我会觉得比较安心。

目前最流行的前端开源框架,有ng2,react,vue, ng2的套路比较深,是一个一站式框架,而其他两个更倾向于做好view这一块,其他由外部插件去实现。uee虽然也以时俱进,借鉴了ng2采用原生ts的方式,推出了ts版本,写法和ng2也比较像,不过累感不爱呀,这一次ng2的组件特性已经非常强大了,被人诟病的脏检查也改进了,窃以为直接native也是可以接受的。

我眼中的uee黑科技相关推荐

  1. 古代的电子计算机,古代也有黑科技:周朝的智能机器人,元朝的电子计算机!...

    科技是人类发展的重要成果.正是一项项科学技术的发明,改变了我们的生活.比如说,有了网络,我们不用出门就能知天下事:有了汽车,不用走路就能轻松跑上百公里:有了飞机就能像鸟儿一样在天空自由飞翔.但是,可能 ...

  2. android 反编译_Box 黑科技——支持手机端反编译

    项目地址: https://github.com/lulululbj/Box 文末扫码获取最新安装包 . 前言 有将近一个月没有更新文章了,一方面在啃 AOSP ,消化起来确实比较慢.在阅读的过程中, ...

  3. 【云周刊】第146期:史上最大规模人机协同的双11,12位技术大V揭秘背后黑科技...

    摘要: 史上最大规模人机协同的双11,12位技术大V揭秘背后黑科技,INTERSPEECH 2017系列 | 语音识别之语言模型技术,机器学习初学者必须知道的十大算法,云数据库SQL Server 2 ...

  4. 黑科技:绕过眼睛植入幻觉,科学家成功在盲人脑海中呈现指定图像!

    来源 | 学术头条(ID:SciTouTiao) 头图 | CSDN付费下载自视觉中国 对于全球 5000 多万盲人来说,重见光明是一个遥不可及的梦想.而为了与盲人朋友进行交互,我们发明了盲文,用各种 ...

  5. 黑科技抗疫,Python开发者大集结!

    2020年初,突如其来的新型冠状病毒肺炎打乱了所有人的节奏,但社会各界迅速团结起来,为抗击疫情贡献出自己的力量.除了捐款捐物外,很多科技公司运用5G.大数据.AI.云计算等新互联网技术,以科技的手段助 ...

  6. 围巾都这么黑科技了,是我见识少了

    有一个永恒的话题: 北方冷一点还是南方冷一点? 答案是:哪里都冷! 冬天最痛苦的莫过于走出空调房-- 刺骨的风直直的从领口处灌进去 那叫一个"透心凉,心飞扬" 缠了好几圈的大围巾却 ...

  7. 帮奶牛找对象?华为云AI黑科技大揭秘

    AI可以用来做什么? 华为云BU总裁郑叶表示,"AI不是一个独立的产品,而是一种 '基本生产力',适用于大部分经济活动,将改变每一个行业.企业和职业,产生倍增效应." 于是,华为的 ...

  8. 阿里云首席科学家闵万里:我们为什么敢挑战一百年的制度,因为黑科技能为挽救生命抢来50%的可能性

    如果急救车不被困在红灯下绝望等待,里面垂危的生命,或者还有希望.也许AI可以做到,让绿灯提前为他敞开生命之路. 编辑 | 鸽子 在这世界上,最令人绝望的等待就是在急救车上,无情的红色信号灯将它一路拦截 ...

  9. 独家 | 我们扒出了这家中国创业公司,竟比苹果iPhone X早两年推出黑科技,还不用借助深度摄像头

    关心AI的人们都关注了此号☝☝☝ 于是,没有iPhone X,我也可以在我仅2000元的安卓机上玩转黑科技了. 记者:鸽子 在我威威天朝,表情包早已泛滥在各类社交应用程序中,如今,咱可以玩点新的包了. ...

最新文章

  1. Keras中神经网络可视化模块keras.utils.visualize_util安装配置方法
  2. Vxworks增加system call
  3. 超干货 | 这些概念可是操作系统的灵魂,你弄懂了几个?
  4. win10如何提高电脑画质_win10电脑怎么提高画质 | 手游网游页游攻略大全
  5. 转数组_Java中IO必杀技-文件转字节数组
  6. 单链表实现集合的交并差Java_单链表表示的集合交,并,差运算,设计采用定义集合,用集合运算表达式求值的方式进行。C语言实现。...
  7. java包装经验_java中基本类型和包装类型实践经验
  8. DXperience 8.2.3
  9. 【计算电磁学】使用FDTD的矩形微带贴片天线MATLAB仿真
  10. 820操作系统(2)进程管理
  11. 开源GIS-01-开源库的编译
  12. 5G C-V2X技术介绍
  13. 如何在 AWS 云中从 Amazon EC2 启动 RHEL 8?
  14. 麦客CEO李卉:实践证明肯钻营的“小而美”亦动人|企服三会系列报道
  15. php 极光短信发送 api
  16. vue 找回密码_找回密码的功能设计
  17. 【C++】limits头文件 numeric_limits
  18. 一些获取免费域名的方法
  19. Android 状态栏工具类(实现沉浸式状态栏 / 变色状态栏)
  20. c51语言单片机打铃系统设计,毕业论文单片机自动控制打铃系统及设计.doc

热门文章

  1. 如何快速查询笔记本序列号
  2. mac top命令,查内存 cpu
  3. Internet Explorer 设置 注册表中设置IE(Windows安全设置之注册表项)
  4. 新版“人生四大悲剧”
  5. 手机wifi延迟测试软件,如何测试无线投屏延时值?同屏延时怎么测? 四画面延时多少?同屏延时 传屏器延时 电脑投屏...
  6. 【算法】图上两点间的最短路径
  7. C++定义类对圆做运算
  8. java和js中替换字符串的方法
  9. 区块链中的智能合约(Smart Contract)
  10. 腾讯大讲堂-1.4亿同时在线背后的故事_学习笔记(一)