Angular遇上CoffeeScript - NgComponent封装

栏目: CoffeeScript · 发布时间: 7年前

内容简介:Angular遇上CoffeeScript - NgComponent封装

Angular遇上CoffeeScript - NgComponent封装

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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网络空间导论

网络空间导论

李良荣、方师师 / 复旦大学出版社 / 2018-6-1 / 38

在互联网蓬勃发展的今天,新闻传播学科该往何处去?在长达半个多世纪的深入研究后,李良荣教授及其团队给出了答案:从“小新闻”走向“大传播”,并撰写了这本开创性的教材:《网络空间导论》。 在本书中,互联网被定义为“空间”——持续演进的数字化现实。为了深刻把握网络空间的内涵,本书提供了六个维度的观察:技术应用、组织架构、政治经济、媒介文化、网络素养、安全治理,并以大胆且富有建设性的观点重新定义了新闻......一起来看看 《网络空间导论》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具