loveky的流水账

注: 文中所有涉及到的AngularJS源码均来自angular-1.2.8版本。 注2: 本文结构为一段代码配一段说明,代码在上,说明在下。 从3月3号到现在,进入新公司也有1个月了。过去这一个月里主要负责公司内部某个DevOps工具开发过程中的前端部分。由于涉及到较多的网页交互,该项目的前端部分使用了AngularJS这个框架。本人这正好借助这个机会进一步了解了AngularJS的相关知识。 这两天项目主体完成,准备上线,算是有了一些自由时间,正好借此机会学习一下AngularJS内部的实现机制。 本篇来说说最常见的directive之一 ngRepeat 该文件的整体结构如下: var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { var NG_REMOVED = '$$NG_REMOVED'; var ngRepeatMinErr = minErr('ngRepeat'); return { transclude: 'element', priority: 1000, terminal: true, $$tlb: true, link: function($scope, $element, $attr, ctrl, $transclude){ ..... } }; function getBlockStart(block) { return block.clone[0]; } function getBlockEnd(block) { return block.clone[block.clone.length - 1]; } }]; ngRepeatDirective是一个数组,它会被传递给directive方法用来生成ngRepeat这个directive。可以看到ngRepeat依赖于$parse和$animate两个服务。$parse用来将字符串解析成javascript函数。$animate用来给DOM改变附加上动画效果。文件最后声明了两个helper方法,会在稍后的分析中介绍到。 接下来把最大的篇幅交给这个directive的核心——link方法。 var expression = $attr.ngRepeat; var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/), trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, lhs, rhs, valueIdentifier, keyIdentifier, hashFnLocals = {$id: hashKey}; if (! ... Read More
刚开始学习AngularJS Directive时,总是不太能搞明白compile和link两个属性的含义和区别。最近写的多一些,读的资料也多了一些,渐渐有了一些理解,简单记录下来: compile属性是一个函数。该函数会针对每一个directive的实例执行一次,在compile阶段: 不能访问scope 元素还没有被插入document 可以修改template,最终结果会被angular缓存 link属性可以有两种配置方式。 link属性可以被设置为一个对象,包含pre, post两个属性,分别对应一个函数(preLink, postLink)。preList,postLink的区别在于执行顺序。preLink是自顶向下的,先父节点,后子节点,postLink正好相反。 .directive{ return { link: { pre: function preLink(){ ... }, post: function postLink() { ... } } } } link属性也可以被直接设置为一个函数,则默认相当于设置了postLink函数。 .directive{ return { link: function link(){ ... } } } 等于 .directive{ return { link: { post: function post() { ... } } } } 由此可见,如果直接将link属性设置为一个函数,则link阶段的执行顺序是自底向上的。 link阶段会针对每一个被RENDERED的directive实例执行一次。此阶段: 可以访问scope(因为controller已经初始化完成) 元素已经被插入document中 不可以修改template(angular会直接使用之前缓存的内容) ... Read More

使用CSS3实现逐格动画
21 February 2014

首先我们有这样一张照片: 照片长度为1184px,高度为75px,共分为24格。 首先我们将DIV大小设置成单格照片的大小,49x75。这样在初始状态下看到的就是第一格的照片。 接下来定义的是最终状态也就是最后一格的状态,通过偏移量背景调整到最后一格。 最后就是定义动画效果,在下面的设置中时长2秒,动画会无限循环下去。 @keyframes wave { to { background-position: -1184px 0 } } @-webkit-keyframes wave { to { background-position: -1184px 0 } } #hahaha { margin: 50px auto; width: 49px; height: 75px; background: url('https://raw.github.com/loveky/loveky.github.io/master/assets/images/css3-stop-animation-background.png') 0 0; -webkit-animation: wave 2s infinite steps(24); animation: 2s wave infinite steps(24); } 效果如下: 由于照片是自己剪辑拼成的,所以偏移量不是太精确。。。
从2011年12月12号到2014年2月28号,不知不觉在上海这座城市度过了798天。 在来eBay之前,我还没用过Git,更没听说过ClearCase 打算离开第一家公司时还没想过今后要做什么,只是厌倦了日复一日没有任何技术含量的工作已经对公司前景非常不看好。当时就是在这样一个迷茫的环境中开始骑驴找马的过程,整个过程并不漫长,只面试里 两家。第一家是苏州一个叫玩啥e族的网站,职位是系统工程师,负责服务器维护,不过在一面之后便杳无音讯。原因大概是因为没啥实际经验。也难怪,在第一家公司虽然也是做系统管理员,但都是客户要做什么就照着文档一步一步敲命令,学到的东西非常有限。第二次面试便是George帮忙联系的上海CSC外派eBay的机会。当时没用过Git,更没听说过ClearCase,并且第一次知道还有SCM这样的工作。不过很巧,eBay当时并没有考虑找一名非常有经验的工程师,而是准备找一个“白板”慢慢培养。也许这也算是缘分,在抱着《Git权威指南》突击了几天后,我居然通过了面试–我当时完全没有抱希望。 海绵吸水般的半年 来到eBay,全新的工作内容,全新的技术,全新的环境。对什么都很新鲜,对什么任务都很热情,每天第一个到,最后一个走。不仅仅是因为需要花时间学习同时完成工作任务,更是因为eBay这样一个大公司有很多东西都很吸引我,吸引我去了解,学习。渐渐的,了解了Git,学习了ClearCase,渐渐的,也能帮Developer解决一些开发过程中遇到的问题,刚刚进入公司时觉得非常“高精尖”的东西也慢慢变得不再神秘。除了纯粹的技术上的进步,我还了解了向eBay这样的大公司,遍布在全球各个site的工程师是如何协同工作;了解了作为一个support engineer如何帮助客户快速解决开发过程中遇到的问题;了解了美国工程师如何思考,解决问题。而最后这一点,也是我认为在这过去的2年多的时间里对我影响最大的。遇到问题时,不应该只是忙于寻求一个解决方案,更重要的是思考问题背后的事情。重要的不是“我能怎样”,而是“我应该怎样”(Do the right thing)。也许这也算是工程师文化的一部分吧。 我“被”离职了 好景不常,来到eBay的半年后,我“被”离职了。起因是新上任的VP推出了一条节省开支的策略,清理掉所有他手下的外派人员。于是我又开始了找工作,由于有在eBay的工作经验,这次工作找起来还算顺利,先后拿到了携程,EMC和一家小公司的职位。工作内容分别是构建一套日志分析系统,做EMC产品的技术支持以及perl脚本开发。虽然找到了工作,但当时其实并不想离开。原因是工作刚刚由熟悉到熟练并且对工作内容又很感兴趣,正要更进一步的学习,此时离开难免有些“不过瘾”。大概是出于对我前半年工作的肯定,老板在最后一刻争取到了一个让我多留在eBay几个月的机会,并最终帮我申请到了专为eBay正式员工的名额。也算是有些“因祸得福”吧。 味道变了 在eBay工作的2年中,每年都有很大的收获。区别在于第一年收获都在工作中,而第二年的收获都在工作之外。在结束了“海绵吸水”似的第一年后,刚刚过去的这一年更多的似乎是各种问题。因为刚到新公司时,所有的精力都在学习和任务上。而等到对工作慢慢熟练之后,精力慢慢转移到对工作本身的思考上来。其实,很多事情是禁不住思考的,每当发现工作中有的事情不是在do the right thing时,我都会如实的讲给manager。所以我一直认为,“唯命是从”的员工不是好员工,因为你没有承担自己思考,反馈的义务。工作并不单单是把事情搞定那么简单。make it work以后更要make it right. Ruby? Rails? 没错,不得不提的主题。过去一年里的业余时间都是围绕他俩展开的。12年年底开始接触Ruby,相较于Perl而言,Ruby更fasion更“性感“更自然。接着我接触到了Sinatra,可以写一些简单的页面。再后来接触到了大名鼎鼎的Rails,并且很快就做出了一个Blog应用。Ruby/Rails的简单,友好深深的吸引着我。接着我开始不满足于自己看书学习了。恰在此时,在RubyChina上看到了xmonkeycn的一个拖延症患者的精益(Lean Startup)实践这篇帖子。于是毫不犹豫的报了茶叶班的中级班,详细的学习了一下Rails,理解了Rails是如何工作的。随后在去年4月份的的RubyTuesday上认识了xmonkeycn。随后帮忙写了一些批量下载照片的脚本 接着便接触到了他的小团队(额外还有1个前端妹子和一个做业务的帅哥)——他们当时正在”密谋“做一些”事情“。就这样,业余时间一边学习茶叶班高级班的课程,一边帮xmonkeycn和他的小伙伴的贡献一些和”低级”的代码。慢慢的,我知道了TDD,开始写测试了,又慢慢的,渐渐的熟悉了CSS和JS。就这样,每天工作上的”抵触情绪“和业余时间学习,coding获得的满足感形成了巨大的反差。我甚至开始幻想做一名全职Ruby/Rails开发人员。一晃大半年过去了,就这样时间到了13年下半年。由于家庭原因,我开始寻找北京的工作机会,在一系列SCM相关职位面试的经历之后,我不得不考虑Ruby这条道路的可能性有多大。于是尝试性的在RubyChina论坛上看起了招聘的信息,并在13年的最后一个月投出了第一份Ruby Engineer的简历。1个月后,我收到了北京一家互联网公司的offer。虽然公司没有eBay大,待遇也没有上海这边好,但在思考过后,还是接受了这个机会。因为life is too short,为何不把时间放在能让自己快乐的事情上呢?何况,只有happy work,才能出彩。趁着年轻,尽管折腾吧! 路在脚下,再出发 还有十来天就要离开这座城市,也许在踏上火车的那一刻会有不舍,也许以后很少再有机会回到这里,但终归这里给我留下了很多美好的回忆,感谢所有的同事,朋友,给我的帮助,鼓励。祝一切都好。 过去的2年多里,我: 感谢我的女朋友,一直没能陪在她身边,有很多亏欠,只希望在以后的日子里慢慢弥补 学会Rails已经一系列相关的技术,并最终转型为一个全职的开发人员 结识了很多好朋友,一直在工作内外给我帮助,不能一一列出姓名,谨祝工作顺利 渐渐的开始锻炼身体,开始跑步 在无人指导的情况下,无师自通,学会了做饭。。。 开始渐渐的学会思考,尝试make it right而不仅仅是make it work 喜欢上了阅读,电子书,纸质书,中文,外文,技术,社科,来者不拒
git clean是干啥的? git clean可以帮你清理workspace中未被git版本控制的文件,比如临时文件,构建出来的二进制文件。 使用方法 如果你的clean.requireForce项没有设置为false,那么每次使用git clean时都要加上-f参数 示例如下,workspace中有2个调试logo时创建的临时png文件,commit之前需要删掉。如果不用git clean的话需要一个一个rm。 LM-SHC-00355679@17:42:26:~/Angular/pomodoro-time (master) => git status -s ?? image/logo1.png ?? image/logo2.png 使用git clean可以快速清楚,当临时文件较多时尤其方便。 LM-SHC-00355679@17:42:30:~/Angular/pomodoro-time (master) => git clean -f Removing image/logo1.png Removing image/logo2.png 有的时候可能需要将当前workspace打包成zip。但是直接打包会将.gitignore里的文件也打进去。这是git clean也可以帮忙。只需加上-x参数。 LM-SHC-00355679@17:48:13:~/Angular/pomodoro-time (master) => cat .gitignore /coverage LM-SHC-00355679@17:48:16:~/Angular/pomodoro-time (master) # -d 参数表示连同目录一起删除 => git clean -xfd Removing coverage/ LM-SHC-00355679@17:48:25:~/Angular/pomodoro-time (master) => ls coverage ls: coverage: No such file or directory 以上就是git clean的基本用法啦。下面介绍下git clean的其他可选参数: -n 并不实际执行删除操作,只显示出将被清理的文件列表 ... Read More