配置Sublime成为Javascript开发环境

我在编写《JavaScript核心概念及实践》一书的时候,为了保证读者学习时可以比较专注语言本身,专门用Swing开发了一个小工具JSEvaluator。 这个工具可以当做JavaScript的简单的IDE,有一个编辑区域,有一些按钮(打开,保存,执行等),执行之后还可以将结果显示在一个面板上。书出版后不断有读者问我如何将这个工具运行起来(我自己写这个工具的时候,并没有release的概念,而且最初的几个版本可用之后,就再也没有花心思维护),单独回复比较耗时,今天早上又收到一位热心读者的邮件,就在这里统一回复一下。 其实JSEvaluator的思想和其他的IDE一样:将一个编辑器和命令行工具结合在一起,编辑器提供编辑功能,然后IDE可以将编辑器中的文本发送给命令行工具执行(使用Rhino),将结果重定向到界面上。 Sublime Text提供的Build功能也可以做到这一点,并且可以使用它更加强大的其他编辑特性,因此推荐各位读者使用这里介绍的方式。 Sublime Text编辑器 Sublime Text是一个文本编辑器,非常轻量级,并且有丰富的插件机制。虽然它不是一个免费软件,但是如果不注册还是可以无限试用下去,除了不定时的弹出一个对话框之外。它在现在的前端开发中非常流行,我作为一个Vim的忠实粉丝,也已经花费了很多时间在Sublime Text上了。 在写书的时候,JavaScript已经比较火了,但是更多的是在Web端。在本地开发的支持上还是比较薄弱。但是现在就不一样了,各个操作系统平台上都已经有了许多本地的JavaScript执行环境。比如Mac自带的jsc,跨平台的node等。 准备工作 如果你在使用Mac OS X,请直接跳到下一步。如果你在使用Windows,请先安装node.js的Windows版本,然后保证node.exe在系统的PATH环境变量中。 自定义build 在Sublime Text中,点击Tools -> Build System -> New build system...,Sublime会打开一个文件,我们来编辑这个文件: { "cmd": ["jsc", "$file"], "selector": "source.js" } 上边这个命令指定了这个build使用的命令是jsc。如果你在Windows下使用node,那么对应的这个文件应该写成: { "cmd": ["node", "$file"], "selector": "source.js" } 如果node.exe不在环境变量PATH中,请保证将其加入。完成这个文件的编辑之后,将其保存为JavaScript.sublime-build文件(Sublime会提示你输入文件名,因此输入JavaScript即可)。 开始开发 接下来你就可以在Sublime中开发并编译JavaScript代码了,应该注意的是,如果你使用的是jsc,那么console.log这样的函数式不能直接使用的,不过你可以很容易的将其重新定义: var console = console || {}; console.log = debug; 这里的debug是Sublime提供的输出函数,它将会把结果输出在Sublime的控制台上。 运行构建的快捷键,在Mac OS X下为(Cmd+B),Windows下为(Ctrl+B)。运行之后,可以看到在编辑器的底部会有一个小的窗口打开,里边的内容就是执行结果了。 其他资料 这里有一个英文版,这里是另一个 这里有一个中文版,以及它的补充 Note:由于我自己不使用Windows平台,也不推荐其他开发者使用,因此关于Windows的部分并没有经过认真测试。

December 21, 2014 · 1 min · 邱俊涛 | Juntao Qiu

一个神奇的Bug

一个神奇的Bug 目前项目是一个非常传统的Web应用,其中有个页面需要用户填写自己的个人信息,包括姓名和出生日期。非常简单的一个小片段,UI看起来是这个样子的: 没有使用现成的datepicker,某个开发人员只是简单的自己收集了一下年,月,日信息,然后在JavaScript中根据填写的值来new了一个Date对象。 然后某天我在做测试的时候,顺手填写了一个日期1986年5月4日,然后奇怪的事情发生了: WTF?,这日期怎么会是非法的呢?于是我又尝试了1986年5月3日和1986年5月5日,一切正常!好奇之下,我找到对应的代码: var dobDay = parseInt($("#personal\\.dobDay").val(), 10); var dobMonth = parseInt($("#personal\\.dobMonth").val(), 10); var dobYear = parseInt($("#personal\\.dobYear").val(), 10); // Note month is not zero based. var dob = null; if (dobDay > 0 && dobMonth > 0 && dobYear > 0) { dob = new Date(dobYear, dobMonth - 1, dobDay, 0, 0, 0, 0); } if (dob === null || dob.getDate() !== dobDay) { valid = false; $("#dob-error").html(this.formMessages.invalidDate); } 从界面上获取用户输入的年,月,日信息,然后根据这三个数字创建一个JavaScript对象。但是奇怪的是,这里有一条判断dob....

September 4, 2014 · 2 min · 邱俊涛 | Juntao Qiu

使用Openlayers可视化GeoJSON数据

OpenLayers 使用OpenLayers可以很容易的搭建基于Web的GIS系统,OpenLayers支持不同的数据源(符合WMS协议的服务器,Google Maps API, Bing Maps,KML以及GeoJSON等等)。通过将不同的数据源的数据整合,我们可以开发出丰富而用户友好的GIS系统。 OpenLayers可以轻松的处理GeoJSON数据,并将其生成矢量层,我们可以将这个层叠加在其他数据源(比如OSM)提供的地图上,以得到一个完整的小应用。 最后的运行结果是这样的: GeoJSON 美国地理信息调查局是一个科学组织,他公开了很多地球上的灾难信息,比如对地震的统计,并提供编程接口。它公开的地震统计信息,包含全世界各地报告过的地震,以及全美所有检测到的地震,并以多种周期(小时,天,周,月等),多种格式(GeoJSON,KML,Atom等),以便应用程序的开发者只用这些数据。 实现 设置基本环境 我们将借助bower来安装所有的代码依赖。首先,我们需要bower将所有的包都安装在components目录下,这个可以通过在当前目录的.bowerrc文件中制定directory: { "directory": "components" } 然后运行bower安装jquery以及openlayers: $ bower install jquery $ bower install openlayers 通过bower安装OpenLayers之后,可以通过OpenLayers自带的build工具将所有的源码合并压缩为一个文件: $ cd components/openlayers/build $ ./build.py #将会在当前目录下生成一个OpenLayers.js的文件 $ mv OpenLayers.js ../ 然后,创建一个简单的HTML文件,引用jquery.js和OpenLayers.js,以及我们的入口脚本app.js,本文所有的代码都只是修改这个文件。 <!DOCTYPE HTML> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Earthquake distribution</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="container"> <div id="map"> </div> </div> <script src="components/jquery/jquery.js" type="text/javascript"></script> <script src="components/openlayers/OpenLayers.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> </body> </html> 还可以运行bower init来将生成bower....

April 15, 2014 · 2 min · 邱俊涛 | Juntao Qiu

使用Mapnik搭建GIS服务器

渲染引擎Mapnik 上一篇文章中大概介绍了Mapnik,它是一个渲染引擎,一般开发中都会使用他的python的bind做开发。 Mapnik的文档写的比较详细,我们这里只是做一些必要的介绍,详细的细节可以参看Mapnik在Github上的文档。 在Mac下,安装Mapnik十分容易,使用brew即可,注意我们在此处带上--with-postgresql选项,使得Mapnik可以通过PostGIS来访问数据库: brew install mapnik --with-postgresql 安装完成之后,可以通过一个小的python脚本来测试: import mapnik map = mapnik.Map(256, 256) map.background = mapnik.Color('red') map.zoom_all() mapnik.render_to_file(map, 'red.png', 'png') 这段脚本可以在当前目录下生成一个红色的256x256的小图片。好了,有了渲染引擎,我们需要一些数据来进行渲染了。 数据源 最通用的数据格式为Shapefiles,目前有很多的免费地理信息供公共下载,我们可以从Metro的站点上下载一些小的数据文件。 $ wget http://osm-extracted-metros.s3.amazonaws.com/chengdu.osm2pgsql-shapefiles.zip $ mkdir chengdu $ cd chengdu $ unzip chengdu.osm2pgsql-shapefiles.zip 这样就得到了一组文件: $ find . -name "*.shp" ./chengdu.osm-line.shp ./chengdu.osm-point.shp ./chengdu.osm-polygon.shp 每一个shp文件都会对应几个其他类型的文件,比如投影信息,属性表等。仅仅查看shp的话,有表示所有点的文件chengdu.osm-line.shp,又表示所有线的chengdu.osm-line.shp,以及表示所有面(区域)的chengdu.osm-polygon.shp文件。 有了这些文件,我们就可以做一些测试了,比如我们首先加载所有的线条,并根据这些线条生成一个图层: import mapnik map = mapnik.Map(800, 800) map.background = mapnik.Color('#ffffff') style = mapnik.Style() rule = mapnik.Rule() point_symbolizer = mapnik.PointSymbolizer() rule.symbols.append(point_symbolizer) style.rules.append(rule) map.append_style('default', style) ds_point = mapnik....

April 12, 2014 · 2 min · 邱俊涛 | Juntao Qiu

如何测试 Service - Angularjs

Service的典型示例 在AngularJS中,Service都是单例的实体,通常会将Service作为向后台交互的数据提供者,所有的需要数据的组件只需要依赖于这个Service即可。 var app = angular.module('MyApp', []); app.factory('SearchSettingService', ['$http', '$q', function($http, $q) { return { setting: function() { var deferred = $q.defer(); $http.get('/settings.json').success(function(result) { deferred.resolve(result); }).error(function(result) { deferred.reject("network error"); }); return deferred.promise; } }; }]); $httpBackend 测试的时候,我们不需要真实的发送HTTP请求来获取数据。如果可以只测试Service的逻辑,当发送请求时,我们将这个请求拦截下来,然后返回一个预定义好的数据即可: it('should have settings from http request', function() { var result; var expected = { "period": "day", "date": "Sat Dec 21 12:56:53 EST 2013", }; httpBackend.expectGET('/settings.json').respond(expected); var promise = settingService.setting(); promise.then(function(data) { result = data; }); httpBackend....

January 4, 2014 · 2 min · 邱俊涛 | Juntao Qiu