也就是最近才开始使用yeoman的。使用yeoman可以快速创建应用程序骨架,自动编译coffee和compass等,把需要重复做的工作减到最少,让开发人员更加专注。
上次使用yeoman生成了一个backbone + coffee + requireJS的项目,相当喜欢这样用CoffeeScript书写的模块化的开发方式,开发体验非常愉快。
之是相对还是比较熟悉AngularJS一些(可以理解为两个都不太熟- -!),所以今天尝试一下使用yeoman构建一个AngularJS + coffee的应用。
之前已经安装好了yeoman,所以直接进行:
安装generator-angular
# npm install -g generator-angular
创建新文件夹
# mkdir angular-with-coffee && cd $_
使用yeoman构建,带上--coffee参数以添加CoffeeScript的支持
# yo angular --coffee
工程生成完毕,此时目录是这样的
启动服务器并watch文件状态,自动编译
grunt server
直接可以进入工作状态。。
创建新的directive
下面用Coffee来完成 http://docs.angularjs.org/guide/directive 里的CurrentTimer
更改view/main.html:
Date format: <input ng-model="format"> <hr/> Current time is: <span my-current-time="format"></span>
controllers/main.coffee:
我们需要完成的是一个directive,controller里把不需要的代码删除掉
'use strict'angular.module('angularWithCoffeeApp') .controller 'MainCtrl', ($scope) -> $scope.format = 'M/d/yy h:mm:ss a'
在命令行输入 yo angular:directive myCurrentTime
,使用yeoman创建一个新的directive,可以看到在script目录下多了 directives
的子目录,并且自动创建了 myCurrentTime.coffee
,同时自动在 test/spec/directives
下面创建了相应的测试脚本
把myCurrentTime.coffee里的东西删掉,输入如下代码
'use strict'angular.module('angularWithCoffeeApp') .directive 'myCurrentTime', ($interval, dateFilter) -> link = (scope, element, attrs) -> format = '' scope.$watch attrs.myCurrentTime , (value) -> format = value updateTime() updateTime = () -> element.text dateFilter(new Date(), format) element.on '$destroy', () -> $interval.cancel(timeoutId) timeoutId = $interval () -> updateTime() , 1000 link : link
注意几点, format = ""
此行是因为这个format的作用域是在link这个函数里,所以需要在这里显式定义,否则在编译时候, scope.$watch
中的format变量会声明为局部变量,就出错了。
为directive编写测试
使用yeoman生成的应用中已经安装好了karma作为测试工具,使用jasmine作为测试工具进行测试。
在 test/spec
下已经有现成的测试脚本。我们来修改一下对于directive的测试脚本。
test/spec/drectives/myCurrentTime.coffee
'use strict'describe 'Directive: myCurrentTime', () -> # load the directive's module beforeEach module 'angularWithCoffeeApp' scope = {} element = {} filter = {} #在此传入$compile和dateFilter beforeEach inject ($rootScope, $compile, dateFilter) -> scope = $rootScope.$new() scope.format = 'M/d/yy h:mm:ss a' filter = dateFilter element = angular.element '<span my-current-time="format"></span>' $compile(element)(scope); scope.$digest() it 'element\'s innerHTML should be a formmated Date ', () -> #element中的内容 dateText = element.html() #使用当前时间和format生成的时间字符串 customTime = filter(new Date(), scope.format) #对比一下 expect(dateText).toBe customTime
这里我们使用directive来compile一个新的myCurrentTime的element,然后判断这个element的内容是不是符合格式的时间字符串。
保存,这时grunt server自动打开一个新的浏览器窗口运行测试,并显示测试通过。
结语
使用yeoman可以更专注的进入工作,可以节省大量的配置时间。而在进行angularJS的开发的时候,使用yeoman进行每一步工作也可以'稍微'规范一点。
并且通常情况下,AngularJS的源文件都是比较繁杂的, 使用coffeeScript进行开发可以使得代码更简单更紧凑且更清晰。
useful links
http://docs.angularjs.org/guide
http://alxhill.com/blog/articles/angular-coffeescript/
http://newtriks.com/2013/04/26/how-to-test-an-angularjs-directive/
原文链接:http://outofmemory.cn/javascript/angularjs-and-coffeescript