Skip to content

Latest commit

 

History

History
206 lines (150 loc) · 5.4 KB

2013-09-17-clojurescript.md

File metadata and controls

206 lines (150 loc) · 5.4 KB
layout title categories tags avatarimg author
post
Luminus手册-ClojureScript
luminus
clojure
luminus
/img/head.jpg
wangyifan

Summary

ClojureScript可以作为JavaScript在客户端的替代品。使用ClojureScript可以 有如下有点:

  • 在客户端和服务端使用相同的语言
  • 在前后端共用相同的代码
  • 简介流畅的语言
  • 使用Leiningen管理依赖关系
  • 不可变数据
  • 功能强大的库
  • Adding ClojureScript Support

最简单的添加ClojureScript支持的方法就是在创建新项目的时候添加+cljs选项 。不过在现有的项目中添加ClojureScript也同样的简单。你只需要在 project.clj文件中添加如下内容即可。

:plugins [...
          [lein-cljsbuild "0.3.0"]]

:hooks [... leiningen.cljsbuild]

:cljsbuild
{:builds [{:source-paths ["src-cljs"]
           :compiler {:output-to "resources/public/js/site.js"
                      :optimizations :advanced}}]}

上面的代码将在项目中添加cljsbuild插件和一个钩子。 所有的命名空间需要在项目根目录下的src-cljs目录内。注意,ClojureScript 文件需要以.cljs结尾。如果文件以.clj结尾,它也会被编译,不过它就无法访 问js命名空间。

Using Libraries

使用ClojureScript的一个好处就是你可以使用Leiningen来管理客户端的依赖。 ClojureScript库和其他库一样都配置在project.clj文件中。

Running the Compiler

开发ClojureScript应用最简单的方法就是自动运行编译器。这样,你的任何修 改都会立即生效。要开启自动编译,只需要输入如下命令:

lein cljsbuild auto

也可以使用一次编译的方式。这将会将所有的js编译到一个js文件中。

lein cljsbuild once

Advanced Compilation and Exports

使用高级编译的话变量名会被编译器压缩。如果要确保函数被编译为js时函数名 不变,那么我们需要保证他们的名字是受保护的。而这只需要添加^:export注解:

(ns main)

(defn ^:export init []
  (js/alert "hello world"))

现在我们可以像这样来调用:

    <script>
    main.init();
    </script>

如果我们在代码里使用js库,那么我们必须要保护我们所调用的函数名。例如, 如果我们想使用AlbumColors库,如果我们这样写:

(defn ^:export init []
  (.getColors (js/AlbumColors. "/img/foo.jpg")
    (fn [[background]]
     (.log js/console background))))

当使用高级编译时AlbumColors和getColors将会被改写。为了不让编译器改写他 们,我们需要创建一个js文件,里面包含了我们需要保护的函数,并在代码里引 用它。

var AlbumColors = {};
AlbumColors.getColors = function() {};

我们把上面的代码放到resource目录下一个叫externs.js文件里面。并在 cljsbuild丽引用它,像这样:

{:source-paths ["src-cljs"]
     :compiler
     {:pretty-print false
      :output-to "resources/public/js/site.js"
      ;;specify the externs file to protect function names
      :externs ["resources/externs.js"]
      :optimizations :advanced}}

Interacting with JavaScript

所有的js函数和变量都是在js这个Namespace的。

*方法调用*

(.method object params)

(.log js/console "hello world!")

*访问属性*

(.-property object)

(.-style div)

*设置属性*

(set! (.-property object))

(set! (.-color (.-style div) "#234567"))

更多的例子请查看Himera文档

Working With the DOM

有不少的库可以访问和修改DOM元素。一般用得比较多的是DominaDommy。 Domina对选择和操作DOM元素做了轻量级的封装。而Dommy是个类似hiccup的模板。

Ajax

Luminus使用cljs-ajax来处理Ajax请求。这个库提供的ajax-request,GET和 POST函数能很方便的发送ajax请求。

*ajax-request* ajax-request是最基本的请求函数,有如下参数:

  • uri - 请求URI
  • method - 一个表示http请求类型的字符串,比如:"PUT", "DELETE"
  • format - 一个表示响应类型的关键字,比如: :json 或者 :edn,默认是 :edn
  • handler - 请求成功的回调函数,以响应为参数
  • error-handler - 请求失败的回调函数,以一个map为参数,map包含了错误信 息,相应的key为: :status 和 :status-text
  • params - 一个包含参数的map,发送给服务器

*GET/POST helpers* GET和POST助手接收一个URL和选项,来简化请求:

  • :handler - 请求成功回调函数
  • :error-handler - 请求失败函数
  • :format - 相应格式化
  • :params - 发送给服务器的参数

和ajax-request参数功能相同。

(ns foo
  (:require [ajax.core :refer [GET POST]]))

(defn handler [response]
  (.log js/console (str response)))

(defn error-handler [{:keys [status status-text]}]
  (.log js/console
    (str "something bad happened: " status " " status-text)))

(GET "/hello")

(GET "/hello" {:handler handler})

(POST "/hello")

(POST "/send-message"
        {:params {:message "Hello World"
                  :user    "Bob"}
         :handler handler
         :error-handler error-handler})