Angular遇上CoffeeScript - NgComponent封装

简介:

angualr meet coffeescript

angualr meet coffeescript

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封装,欢迎多多交流。


本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/p/angular-meet-coffeescript.html,如需转载请自行联系原作者

目录
相关文章
|
资源调度 JavaScript 容器
Angular封装WangEditor富文本组件
Angular封装WangEditor富文本组件
343 0
angular的format封装
在标签上使用管道符进行format
|
前端开发 JavaScript
【Angular教程】组件动效/动态组件/视图封装模式
【Angular教程】组件动效/动态组件/视图封装模式
276 0
【Angular教程】组件动效/动态组件/视图封装模式
|
7月前
|
API 开发者 UED
PrimeFaces:JSF的魔法衣橱,解锁UI设计的无限可能!
【8月更文挑战第31天】本文介绍如何结合 JSF(JavaServer Faces)和 PrimeFaces 构建美观且功能强大的现代用户界面。PrimeFaces 提供丰富的 UI 组件库,包括按钮、输入框、数据网格等,支持现代 Web 标准,简化界面开发。文章通过具体示例展示如何使用 `&lt;p:inputText&gt;` 和 `&lt;p:calendar&gt;` 等组件创建用户表单,并用 `&lt;p:dataTable&gt;` 展示数据集合,提升 JSF 应用的易用性和开发效率。
107 0
|
7月前
|
开发者 安全 SQL
JSF安全卫士:打造铜墙铁壁,抵御Web攻击的钢铁防线!
【8月更文挑战第31天】在构建Web应用时,安全性至关重要。JavaServer Faces (JSF)作为流行的Java Web框架,需防范如XSS、CSRF及SQL注入等攻击。本文详细介绍了如何在JSF应用中实施安全措施,包括严格验证用户输入、使用安全编码实践、实施内容安全策略(CSP)及使用CSRF tokens等。通过示例代码和最佳实践,帮助开发者构建更安全的应用,保护用户数据和系统资源。
91 0
|
7月前
|
开发者 C# C++
揭秘:如何轻松驾驭Uno Platform,用C#和XAML打造跨平台神器——一步步打造你的高性能WebAssembly应用!
【8月更文挑战第31天】Uno Platform 是一个跨平台应用程序框架,支持使用 C# 和 XAML 创建多平台应用,包括 Web。通过编译为 WebAssembly,Uno Platform 可实现在 Web 上运行高性能、接近原生体验的应用。本文介绍如何构建高效的 WebAssembly 应用:首先确保安装最新版本的 Visual Studio 或 VS Code 并配置 Uno Platform 开发环境;接着创建新的 Uno Platform 项目;然后通过安装工具链并使用 Uno WebAssembly CLI 编译应用;最后添加示例代码并测试应用。
222 0
|
7月前
|
前端开发 开发者 安全
JSF支付功能大揭秘:探索如何在Java世界中实现安全无缝的在线支付体验
【8月更文挑战第31天】在电子商务和在线交易日益普及的今天,实现在线支付功能已成为许多Web应用的必备需求。JavaServer Faces (JSF) 作为一种流行的Java Web框架,提供了丰富的组件和工具来构建用户界面,包括与支付网关集成以实现在线支付。支付网关是处理信用卡和借记卡支付的系统,在商家和银行之间起到桥梁作用。本文将探讨如何使用JSF与支付网关集成,以及实现在线支付功能时需要考虑的关键点
74 0
|
7月前
|
开发者 前端开发 开发框架
JSF与移动应用,开启全新交互体验!让你的Web应用轻松征服移动设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,移动设备的普及使得构建移动友好的应用变得至关重要。尽管JSF(JavaServer Faces)主要用于Web应用开发,但结合Bootstrap等前端框架,也能实现优秀的移动交互体验。本文探讨如何在JSF应用中实现移动友好性,并通过示例代码展示具体实现方法。使用Bootstrap的响应式布局和组件可以确保JSF页面在移动设备上自适应,并提供友好的表单输入和提交体验。尽管JSF存在组件库较小和学习成本较高等局限性,但合理利用其特性仍能显著提升用户体验。通过不断学习和实践,开发者可以更好地掌握JSF应用的移动友好性,为Web应用开发贡献力量。
69 0
|
7月前
|
JavaScript 开发者
从零基础到实战应用:Angular入门指南带你一步步构建你的第一个Web应用——全面介绍环境搭建、项目创建、组件开发与应用集成
【8月更文挑战第31天】本文档是针对初学者的Angular入门指南。通过详细步骤与示例代码,教你如何使用Angular CLI搭建开发环境、创建新项目、添加及配置组件,并运行首个应用。Angular是由Google开发的强大Web框架,专为高效构建复杂单页应用设计。按照本指南操作,你将能够快速上手Angular,开启Web应用开发之旅。
314 0