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

See the Pen Angular meet CoffeeScript by green (@greengerong) on CodePen.

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

Angular遇上CoffeeScript - NgComponent封装的更多相关文章

  1. CoffeeScript NgComponent

    Angular遇上CoffeeScript - NgComponent封装 CoffeeScript是基于JavaScript的一门扩展小巧语言,它需要编译成JavaScript,然后再运行与浏览器或 ...

  2. 当KDS晶振遇上爱普生晶振国内生产厂家该如何抉择?

    当KDS晶振遇上爱普生晶振国内生产厂家该如何抉择?       全球做晶振行业的公司有很多,单说深圳一个城市就有几十上百家正规的晶振厂家,深圳市金洛电子就是其中之一.我们不光代理日本和台湾多家排得上名 ...

  3. dynamic遇上ADO.NET

    传说中的dynamic dynamic是个不合群.不按规则办事的家伙,可以说是个异形,但更恐怖的是它又是无所不知的,任何事情都难不了它(咳咳,它似乎与Lambda表达式是死对头).这令人想起<死 ...

  4. 当微信小程序遇上filter~

    在微信小程序的开发过程中,当你想要实现不同页面间的数据绑定,却为此抓耳饶腮时,不妨让微信小程序与filter 来一场完美的邂逅,相信会给你带来别样的惊喜~ 前段时间被安利了一个很实用的公众号-前端早读 ...

  5. 微服务中台落地 中台误区 当中台遇上DDD,我们该如何设计微服务

    小结: 1. 微服务中台不是 /1堆砌技术组件就是中台 /2拥有服务治理就是中台 /3增加部分业务功能就是中台 /4Cloud Native 就是中台 https://mp.weixin.qq.com ...

  6. MVC遇上bootstrap后的ajax表单模型验证

    MVC遇上bootstrap后的ajax表单验证 使用bootstrap后他由他自带的样式has-error,想要使用它就会比较麻烦,往常使用jqueyr.validate的话只有使用他自己的样式了, ...

  7. 敏捷遇上UML-需求分析及软件设计最佳实践(郑州站 2014-6-7)

      邀请函: 尊敬的阁下:我们将在郑州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实 ...

  8. 敏捷遇上UML—软创基地马年大会(广州站 2014-4-19)

        我们将在广州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战技巧. 时间:2 ...

  9. 敏捷遇上UML——软创基地马年大会(深圳站 2014-3-15)

    邀请函: 尊敬的阁下: 我们将在深圳为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战 ...

随机推荐

  1. 二.TimesTen原理及应用场景

    声明:本文章转自麻袋爸爸 一,TimesTen应用场景 在谈论TimesTen内存数据库应用场景之前,我们先来介绍一下什么是内存数据库,及其工作原理吧.内存数据库,顾名思义就是将数据存放在内存中,并通 ...

  2. T-SQL 递归

    WITH TEMP ([ID], [PARENTID]) AS (SELECT UNIQUEID ,PID FROM [DBO].TB_DEPTINFO D WHERE PID = @ParentId ...

  3. Javascript 构造函数原型继承机制

    我们先聊聊Js的历史,1994年Netscape公司发布了Navigator浏览器0.9班.这是历史上第一个比较成熟的网络浏览器.轰动一时.但是,这个版本的浏览器只能用来浏览,不具备交互功能,最主要的 ...

  4. 动态SQL 学习

    <select id="findUser" parameterType="Map" resultType="User">     ...

  5. React Native MAC上环境搭建笔记

    今天花了一点时间搭建了一下react native环境,在这个过程中遇到了一些问题,处理并总结一下,年纪大了记性不好,只能多写写...真是岁月不饶人啊! 第一步:安装最新版本的Xcode工具 第二步: ...

  6. MVC Html.BeginForm 与 Ajax.BeginForm 使用总结

    最近采用一边工作一边学习的方式使用MVC5+EF6做一个Demo项目, 期间遇到不少问题, 一直处于研究状态, 没能来得及记录. 今天项目进度告一段落, 得以有空记录学习中遇到的一些问题. 由于MVC ...

  7. SOAPUI使用教程-测试JDBC数据库

    soapUI中有除了开源版本的一些非常实用的功能: 使用在项目级配置的JDBC连接 使用向导创建复杂的查询. 结果显示XML输出视图(以及该使用向导在此视图中提供的XPath断言). 提供JDBC连接 ...

  8. 图论 - Travel

    Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n. Among n(n− ...

  9. 回流(reflow)与重绘(repaint)

    最近项目排期不紧,于是看了一下之前看了好久也没看明白的chrome调试工具的timeline.但是很遗憾,虽然大概懂了每一项是做什么的,但是用起来并不能得心应手.所以今天的重点不是timeline,而 ...

  10. 基础3.Jquery操作Dom

                  1 内部插入节点 <body> <ul id="city"> <li id="bj" name=&qu ...