Angular遇上CoffeeScript - NgComponent封装

CoffeeScript是基于JavaScript的一门扩展小巧语言,它需要编译成JavaScript,然后再运行与浏览器或者Nodejs平台。JavaScript由于商业原因10天时间就匆忙诞生,所以存在很多弊病。但如《JavaScript精粹》一书中所说:JavaScript也存在着一颗华丽的心脏,如果我们能避开JavaScript中的“坑”,使用其精华的部分,这将是一门令人爱不释手的语言. 而CoffeeScript则是尝试使用这部分简洁的方式展示JavaScript的这部分优秀的精华,避免那些困扰JavaScript开发者的“坑”.CoffeeScript借鉴于Python和Ruby这两门语言,函数式风格、鸭子类型、OO风格一体的一门简洁语言。

Angularjs从2012年以来是火极一时的前端MVVM框架,它引入了module、双向绑定、依赖注入、Directive、MVVM等机制。更多资料参见博主其他博文。当Angular遇见CoffeeScript这门语言,将会发生什么呢?

想让我们来看一眼笔者利用CoffeeScript对Angular1.x代码的封装后效果。

## controller
class DemoController extends NgComponent
@inject 'demoService'
@controller 'ng.green.demo' __init__: =>
@demoService.getLang().then (data) =>
@lang = data ## service
class DemoService extends NgComponent
@inject '$q'
@service 'ng.green.demo' getLang: =>
data = data : ['JavaScript', 'CoffeeScript', 'TypeScript', 'ES6']
@$q.when(data) ## directive controller
class JsonDumpController extends NgComponent
@inject '$log'
@controller 'ng.green.demo' __init__: =>
@$log.info('This is form directive controller') ## directive
class JsonDumpDirective extends NgComponent
@inject '$timeout', '$http', '$cacheFactory', '$log'
@directive 'ng.green.demo'
restrict: 'EA'
templateUrl: '/jsonDump.html'
scope:
json: "="
controller: 'JsonDumpController'
link: (scope, elm, iAttrs) =>
@$timeout (() => @$log.info '$timeout & $log injector worked on link function!' ), 100

有了上面的对controller、service、directive的定义,则我们可以如下方式使用:

<div ng-app="ng.green.demo" ng-controller="DemoController as demo" class="container">
<json-dump json="demo.lang"></json-dump>
<script type="text/ng-template" id="/jsonDump.html">
<hr />
<pre></pre>
</script>
</div>

不知各位看官对如上代码感觉如何?是不是更简化、语义化、有点ng的感觉。其中笔者还有意模仿Python,如init作为初始化方式。在这里每个class会自声明组件类型,以及声明式注入,module自注册。

不管如何看,下面我来看看NgComponent到底做了什么?

class NgComponent
@controller: (moduleName, moduleResolver) ->
componentName = @$$componentName(true)
angular.module(moduleName, moduleResolver).controller componentName, @ @service: (moduleName, moduleResolver) ->
componentName = @$$componentName()
angular.module(moduleName, moduleResolver).service componentName, @ @directive: (moduleName, moduleResolver) ->
componentName = @$$componentName().replace('Directive','')
directiveClass = @
directiveFactory = (args...) ->
new directiveClass(args...)
directiveFactory.$inject = @$inject
angular.module(moduleName, moduleResolver).directive componentName, directiveFactory @$$componentName: (upperCaseFirstLetter = false) ->
# regex for ie
componentName = @name || @toString().match(/function\s*(.*?)\(/)?[1]
if upperCaseFirstLetter
firstLetter = componentName.substr(0,1).toUpperCase()
else
firstLetter = componentName.substr(0,1).toLowerCase()
(componentName = "#{firstLetter}#{componentName.substr(1)}") unless upperCaseFirstLetter
componentName @inject: (args...) ->
@$inject = args constructor: (args...) ->
for key, index in @constructor.$inject
@[key] = args[index] @__init__?()

在NgComponent中定义了controller、service、directive注册接口,这里可以是声明创建module,也可以是在已声明的module上注册这些组件类型。对于组件命名也才采用了约定胜于配置,它们都以class类型为基础,controller为首字母大写的驼峰命名,service则首字母小写驼峰命名,directive则会去掉Directive标记并首字母小写注册。

同时这里也声明了@inject方法,使得我们可以在定义在类型之上定义$inejct属性,Angular的注入声明。对于Angular的注入服务,在构造函数中会将他们一一添加到当前类实例对象之上。在依赖添加完毕后,也会调用对象初始化方法,这里是模拟Python的init

Demo效果可以在codepen查看 http://codepen.io/greengerong/pen/EVVQZg?editors=101

本文笔者的突发奇想,希望能给读者一些启发,也许你还有更好的DSL封装,欢迎多多交流。

CoffeeScript NgComponent的更多相关文章

  1. Angular遇上CoffeeScript - NgComponent封装

    CoffeeScript是基于JavaScript的一门扩展小巧语言,它需要编译成JavaScript,然后再运行与浏览器或者Nodejs平台.JavaScript由于商业原因10天时间就匆忙诞生,所 ...

  2. CoffeeScript实现Python装潢器

    在上篇Angular遇上CoffeeScript – NgComponent封装中,我们讲述了CoffeeScript这门小巧的语言,摒弃JavaScript中糟粕(“坑”)部分,并将JavaScri ...

  3. emmet,jade,haml, slim,less,sass,coffeescript等的实战优缺点

    摘要: 文章背景,来自于群内周五晚上的一次头脑风暴式的思维碰撞交流活动. 随着前端技术的蓬勃发展, 各种新技术随着生产力的需要不断的涌入我们的视野, 那今天探讨的话题是这些新时代的前端兵器谱: 一. ...

  4. CSS3与页面布局学习总结(七)——前端预处理技术(Less、Sass、CoffeeScript、TypeScript)

    CSS不像其它高级语言一样支持算术运算.变量.流程控制与面向对象特性,所以CSS样式较多时会引起一些问题,如修改复杂,冗余,某些别的语言很简单的功能实现不了等.而javascript则是一种半面向对象 ...

  5. Coffeescript实现canvas时钟

    前言 参照Mozilla 官方教程,要在Canvas上画动画时钟,思路非常有意思. 把动画看作是多个帧组成,定时每个时间点在Canvas上画一帧来实现动画.而Mozilla 官方教程画图实现的思路有意 ...

  6. CSS3与页面布局学习笔记(七)——前端预处理技术(Less、Sass、CoffeeScript、TypeScript)

    CSS不像其它高级语言一样支持算术运算.变量.流程控制与面向对象特性,所以CSS样式较多时会引起一些问题,如修改复杂,冗余,某些别的语言很简单的功能实现不了等.而javascript则是一种半面向对象 ...

  7. coffeeScript中类的多态[学习篇]

    类的一大应用就是多态.多态是一个面向对象编程的高级术语----“一个东西可编程很多不同的东西,但不是任何东西”.[引自coffeescript深入浅出] class Shape constructor ...

  8. coffeeScript中类的继承[学习篇]

    只是在看深入浅出coffeescript中感觉真的很好,不光是coffe写法简单,生成的js也值得学习,废话不多说了,直接抄个书上的例子 class Pet constructor: -> @i ...

  9. 《CoffeeScript应用开发》学习:第五章 CoffeeScript中的类

    在CoffeeScript中定义类 在CoffeeScript中,使用class定义类,使用关键字new实例化对象. 给类绑定方法 class Airplane takeOff: -> cons ...

随机推荐

  1. live555 for Android

    因为Live555 包中未提供Android 的config 所以编译器来比較麻烦,须要自己编写Android.mk ,下面是我通过 改动 现有的config文件,在cygwin实现 编译的过程,co ...

  2. 当执行游戏0xc000007b错误的解决方法

    如图,这个错误使无数玩家烦恼. 出现这个错误,可能是硬件的问题,也可能是软件的问题.可是,因为硬件引起该问题的概率非常小,而且除了更换硬件之外没有更好的解决方法,因此本文将具体介绍怎样通过软件解决此问 ...

  3. key 串口

    /******************************************************************** 函数功能:往串口发送一字节数据(可通过超级终端或者串口调试助 ...

  4. 人们的Live Meeting系列 (floyd)

    人活着系列之开会 Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 人活着假设是为了事业.从打工的到老板的,个个都在拼搏,奋斗了多年最终有了非凡成就.有了一 ...

  5. Python使用subprocess的Popen要调用系统命令

    当我们须要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.可是这两个命令过于简单.不能完毕一些复杂的操作,如给执行的命令提供输入或者读取命令的输出, ...

  6. 查看linux信息

    1.操作系统内核 cat /proc/version 2.操作系统版本 head -n 1 /etc/issue # 查看操作系统版本 3.查看cpu信息 more /proc/cpuinfo --- ...

  7. Lua相关的知识

    http://stackoverflow.com/questions/5438751/how-to-debug-lua-remotely http://cn.bing.com/search?q=org ...

  8. struts2充分国际化案例 错误解决

    在struts2中须要做国际化的有: jsp页面的国际化,action错误信息的国际化,转换错误信息的国际化.校验错误信息的国际化 在之前的样例中已经做过和国际化相关的样例了,在struts.xml中 ...

  9. 【OpenCV新手教程之十八】OpenCV仿射变换 &amp; SURF特征点描写叙述合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)  ...

  10. Chrome console(转)

    阅读目录 写在前面 谷歌控制台Elements面板 查看元素上绑定的事情 样式操作 总况 console.log console.info console.error console.warn con ...