coffeescript

CoffeeScript是一种基于JavaScript的新编程语言。 CoffeeScript提供了一种干净的语法,该语法应吸引喜欢Python或Ruby的任何人,并且还提供了许多受Haskell和Lisp等语言启发的功能性编程功能。

在本系列的第1部分中,您了解了使用CoffeeScript而不是仅使用JavaScript的好处。 您设置了开发环境并运行了脚本。 在第2部分中 ,您通过尝试许多功能同时解决了数学问题,探索了CoffeeScript编程语言。

在本文中,您将创建一个示例CoffeeScript应用程序。 客户端和服务器端代码都将完全用CoffeeScript编写。 您还可以下载本文中使用的源代码。

由CoffeeScript支持的搜索

常用缩写
  • JSON:JavaScript对象表示法
  • UI:用户界面

您将创建的示例应用程序使用户可以输入搜索词,同时搜索Google和Twitter,然后显示合并的结果。 应用程序的客户端获取用户输入的数据,并将其发送到服务器以获取结果。 从服务器返回结果后,客户端将为结果创建UI元素并将其显示在屏幕上。 现在,不必担心服务器端如何工作。

首先定义应用程序的数据模型。 该应用程序将显示搜索结果,因此定义一个SearchResult类。 清单1显示了定义。

清单1.基本SearchResult
class SearchResultconstructor: (data) ->@title = data.title@link = data.link@extras = datatoHtml: -> "<a href='#{@link}'>#{@title}</a>"toJson: -> JSON.stringify @extras

SearchResult类非常简单。 它:

  • 从定义两个成员变量的构造函数开始: titlelink
  • 在传递给构造函数的数据对象中查找这两个值。
  • 存储传递给成员变量extras的其余数据。

    这将很方便,因为您知道应用程序中将有两种不同类型的搜索结果(来自Google的搜索结果和来自Twitter的搜索结果)。

  • SearchResult类定义两个方法:
    • toHtml ,它利用CoffeeScript的字符串插值功能从SearchResult实例中创建一个简单HTML字符串。
    • toJson ,用于将SearchResult对象转换为JSON字符串。

清单1中的类提供了搜索结果的基本功能。 您将从Google和Twitter的搜索结果中获取更多数据。 通过为每种类型的搜索结果创建子类来对此建模。 清单2显示了Google搜索结果的类型。

清单2. GoogleSearchResult
class GoogleSearchResult extends SearchResultconstructor: (data) ->super data@content = @extras.contenttoHtml: ->"#{super} <div class='snippet'>#{@content}</div>"

清单2显示了CoffeeScript中如何轻松进行面向对象的编程。 GoogleSearchResult扩展了清单1中的基本SearchResult类。 它的构造函数调用超类的构造函数。 如果您曾经用JavaScript完成类样式的继承,那么您就会知道这是多么棘手。 清单3显示了生成JavaScript。

清单3. GoogleSearchResult JavaScript
GoogleSearchResult = (function() {__extends(GoogleSearchResult, SearchResult);function GoogleSearchResult(data) {GoogleSearchResult.__super__.constructor.call(this, data);this.content = this.extras.content;}GoogleSearchResult.prototype.toHtml = function() {return "" + GoogleSearchResult.__super__.toHtml.apply(this, arguments)
+ " <div class='snippet'>" + this.content + "</div>";};return GoogleSearchResult;
})();

要调用超类的构造函数,必须在__super__变量中保留超类的实例(名称可以是任何东西),然后显式调用构造函数。 回到清单2 ,您可以看到CoffeeScript简化了这件事。 请注意,该示例在GoogleSearchResult类中定义了一个名为content的新实例变量。 这基本上是搜索结果所指向的网页HTML片段。 GoogleSearchResult具有此功能并不奇怪,但基类却没有。 最后,请注意toHtml方法的重写。 该示例使用超类的toHtml方法,但还使用内容片段附加了一个额外的div 。 再次查看清单3 ,以了解如何完成对超类的toHtml方法的调用。 因为您有一个GoogleSearchResult子类,所以还需要一个TwitterSearchResult子类,如清单4所示。

清单4. TwitterSearchResult
class TwitterSearchResult extends SearchResultconstructor: (data) ->super data@source = @extras.from_user@link = "http://twitter.com/#{@source}/status/#{@extras.id_str}"@title = @extras.texttoHtml: ->"<a href='http://twitter.com/#{@source}'>@#{@source}</a>: #{super}"

TwitterSearchResult类遵循与清单2中的GoogleSearchResult类相同的模式。 它的构造函数利用了其超类的构造函数。 它也是:

  • 定义自己的成员变量,称为source
  • 使用字符串模板及其成员变量构造link成员变量。
  • title成员变量重置为与输入数据不同的字段。
  • 覆盖超类的toHtml方法,并向创建推文的用户添加链接。

CoffeeScript的字符串插值再次使创建新类时使用超类的toHtml方法变得容易。 要调用超类的toHtml方法,只需调用super 。 您可能很想调用super.toHtml ,但是没有必要,这样做实际上会导致错误。 CoffeeScript表示您想在超类上调用相同的方法,从而使您的生活变得更加轻松。

现在,您已经拥有了应用程序所需的数据结构,并且可以开始编写一些客户端逻辑。 使用工作后端测试代码会容易得多。 因为没有,所以我们使用下一个最好的东西:模拟数据。

使用模拟数据

在构建像现代Web应用程序这样的客户端服务器应用程序时,通常需要在应用程序的两个部分相遇之处创建共享接口,然后创建模拟数据。 这使您可以并行开发应用程序的客户端和服务器部分。 该方法在CoffeeScript上特别有效,因为您可以在客户端和服务器上使用相同的编程语言。 清单5显示了来自Google的模拟搜索结果。

清单5.模拟Google搜索结果
mockGoogleData = [GsearchResultClass:"GwebSearch",link:"http://jashkenas.github.com/coffee-script/",url:"http://jashkenas.github.com/coffee-script/",visibleUrl:"jashkenas.github.com",cacheUrl:"http://www.google.com/search?q\u003dcache:nuWrlCK4-v4J:jashkenas
.github.com",title:"\u003cb\u003eCoffeeScript\u003c/b\u003e",titleNoFormatting:"CoffeeScript",content:"\u003cb\u003eCoffeeScript\u003c/b\u003e is a little language that
compiles into JavaScript. Underneath all of   those embarrassing braces and
semicolons, JavaScript has always had a \u003cb\u003e...\u003c/b\u003e",GsearchResultClass:"GwebSearch",link:"http://en.wikipedia.org/wiki/CoffeeScript",url:"http://en.wikipedia.org/wiki/CoffeeScript",visibleUrl:"en.wikipedia.org",cacheUrl:"http://www.google.com/search?q\u003dcache:wshlXQEIrhIJ
:en.wikipedia.org",title:"\u003cb\u003eCoffeeScript\u003c/b\u003e - Wikipedia, the free
encyclopedia",titleNoFormatting:"CoffeeScript - Wikipedia, the free encyclopedia",content:"\u003cb\u003eCoffeeScript\u003c/b\u003e is a programming language
that transcompiles to JavaScript. The   language adds syntactic sugar inspired by
Ruby, Python and Haskell to enhance \u003cb\u003e...\u003c/b\u003e",GsearchResultClass:"GwebSearch",link:"http://codelikebozo.com/why-im-switching-to-coffeescript",url:"http://codelikebozo.com/why-im-switching-to-coffeescript",visibleUrl:"codelikebozo.com",cacheUrl:"http://www.google.com/search?q\u003dcache:VDKirttkw30J:
codelikebozo.com",title:"Why I\u0026#39;m (Finally) Switching to \u003cb\u003eCoffeeScript
\u003c/b\u003e - Code Like Bozo",titleNoFormatting:"Why I\u0026#39;m (Finally) Switching to CoffeeScript -
Code Like Bozo",content:"Sep 5, 2011 \u003cb\u003e...\u003c/b\u003e You may have already heard
about \u003cb\u003eCoffeeScript\u003c/b\u003e and some of the hype surrounding it
but you still have found several reasons to not make the \u003cb\u003e...
\u003c/b\u003e"
]

显然,使用CoffeeScript的简单语法,甚至可以轻松创建模拟数据。 该示例显示CoffeeScript中的对象文字。 清单5是一个数组。 额外的缩进用于指示对象,并且该对象的每个属性都再次缩进。 此代码与JSON相比具有优势。 空白代替大括号。 它们就像JavaScript文字一样,其中的属性不在引号中。 使用JSON时,这些属性也必须加引号。

清单6显示了Twitter搜索结果的类似模拟数据。

清单6.模拟Twitter搜索结果
mockTwitterData = [created_at:"Wed, 09 Nov 2011 04:18:49 +0000",from_user:"jashkenas",from_user_id:123323498,from_user_id_str:"123323498",geo:null,id:134122748057370625,id_str:"134122748057370625",iso_language_code:"en",metadata:recent_retweets:4,result_type:"popular"profile_image_url:"http://a3.twimg.com/profile_images/1185870726/gravatar
_normal.jpg",source:"<a href="http://itunes.apple.com/us/app/twitter/id409789998?mt
=12&quot; rel="nofollow">Twitter for Mac</a>",text:""CoffeeScript [is] the closest I felt to the power I had twenty
years ago in Smalltalk" - Ward Cunningham (http://t.co/2Wve2V4l) Nice.",to_user_id:null,to_user_id_str:null
]

清单6中的模拟数据与清单5中的模拟数据类似,但具有特定于Twitter的字段。 现在,您只需要创建一个返回此模拟数据的接口。 清单7显示了另一个完成该任务的类。

清单7.一个模拟搜索引擎类
class MockSearchsearch: (query, callback) ->results = google: (new GoogleSearchResult obj for obj in mockGoogleData)twitter: (new TwitterSearchResult obj for obj in mockTwitterData)callback results

MockSearch类具有一个称为search方法。 它有两个参数:用于搜索的querycallback函数。 MockSearch快速返回结果,但是真正的搜索将需要通过网络与服务器对话。 要使用JavaScript处理此问题并确保您不会导致UI冻结,通常应使用回调函数。

下一步将创建一个名为results的对象。 您再次使用CoffeeScript的对象文字语法。 results对象具有两个字段: googletwitter 。 每个字段的值都使用数组理解表示。 该表达式将创建适当类型的SearchResult (对于Google来说是GoogleSearchResult ,对于Twitter来说是TwitterSearchResult )的数组。 最后,将callback函数与传递给它的results对象一起调用。

模拟搜索正在运行,因此您可以编写与UI相关的客户端代码。

将所有内容整合到浏览器中

在将UI粘贴到应用程序代码之前,请先查看将要使用的UI。 清单8显示了一个非常简单的网页。

清单8. CoffeeSearch网页
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"><html lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>CoffeeSearch</title><script type="text/javascript" src="search.js"></script>
</head>
<body><div><label for="searchQuery">Keyword:</label><input type="text" name="searchQuery" id="searchQuery"></input><input type="button" value="Search" onclick="doSearch()"/></div><div class="goog" id="gr"/><div class="twit" id="tr"/>
</body>
</html>

上面的网页具有用于输入关键字并将其传递给搜索引擎的基本形式。 它定义了两个部分,可以将搜索结果添加到其中。 该网页未定义JavaScript。 相反,所有内容都在一个名为search.js的文件中,该文件将为CoffeeScript的编译版本。 请注意,单击搜索按钮后,将调用一个名为doSearch的函数。 此函数必须在search.js文件中; 这是search.js文件中唯一尚未出现的内容。 清单9显示了CoffeeScript中的定义。

清单9.网页的doSearch函数
@doSearch = ->$ = (id) -> document.getElementById(id)kw = $("searchQuery").valueappender = (id, data) ->data.forEach (x) -> $(id).innerHTML += "<p>#{x.toHtml()}</p>"ms = new MockSearchms.search kw, (results) ->appender("gr", results.google)appender("tr", results.twitter)

您可能会注意到该函数有一个@前面加上符号(快捷方式this )。 在脚本的顶层定义时, this成为全局对象。 对于网页中的脚本,全局对象是window对象,它将允许您在清单8中看到的网页中引用它。

doSearch函数仅用几行代码即可完成很多工作。 代码:

  • 定义一个称为$的本地函数,该函数基本上是对有用的document.getElementById函数的快捷方式。 使用它来获取在清单8的搜索表单中输入的关键字。
  • 定义另一个称为appender局部函数,它将使用DOM中的元素ID和数组。 然后,它将遍历数组,创建HTML字符串,并使用给定ID附加到元素。
  • 创建一个MockSearch对象并调用其search方法。
  • 从表单传递关键字并创建回调函数。

    回调函数使用appender将来自Google的搜索结果附加到一个div ,将来自Twitter的搜索结果附加到另一个div

现在,您可以简单地编译所有代码并进行部署。 图1显示了包含模拟数据的网页。

图1.包含模拟数据的搜索页面

该示例可能看起来并不令人印象深刻,但它演示了客户端所需的所有功能。 尽管您尚未对服务器端进行编码,但是只要服务器端代码生成的数据像模拟数据一样,您就可以确信该应用程序将正常运行。

结论

在本文中,我将CoffeeScript带出实验室,并用它来开始构建真实的东西。 与node.js结合使用,CoffeeScript使您有机会使用相同的优美编程语言编写完整的应用程序,客户端和服务器。 在本系列的最后一部分中,当构建应用程序的服务器端时,您已准备好重用某些相同的代码。 敬请关注。


翻译自: https://www.ibm.com/developerworks/web/library/wa-coffee3/index.html

coffeescript

coffeescript_在客户端上使用CoffeeScript相关推荐

  1. coffeescript_在服务器上使用CoffeeScript

    coffeescript CoffeeScript是一种基于JavaScript的新编程语言,它提供了一种干净的语法,该语法应吸引喜欢Python或Ruby的任何人. 它还提供了许多受Haskell和 ...

  2. ADSL的PPPOE拨号客户端上的ppp authentication pap “callin”的正确理解

    ADSL的PPPOE拨号客户端上的ppp authentication pap "callin"的正确理解 对callin参数的理解一定要注意,很容易单让初学者通过"中国 ...

  3. SSM项目使用GoEasy 获取客户端上下线实时状态变化及在线客户列表

    一.背景 上篇SSM项目使用GoEasy 实现web消息推送服务是GoEasy的一个用途,今天我们来看GoEasy的第二个用途:订阅客户端上下线实时状态变化.获取当前在线客户数量和在线客户列表.截止我 ...

  4. java文件客户端下载_使用Java写一个minio的客户端上传下载文件

    标签:color   ati   tty   java   system   wired   format   media   param 前言: 确保已经安装了minio的服务端 代码: pom.x ...

  5. JAVA客户端数据传输_java模拟TCP通信实现客户端上传文件到服务器端

    java模拟TCP通信实现客户端上传文件到服务器端,供大家参考,具体内容如下 客户端 package com.zr; import java.io.FileInputStream; import ja ...

  6. java json写入内存_如何在客户端上减少JSON.stringify使用的内存量?

    使用JSON.stringify将大型javascript对象转换为字符串时,有没有办法减少客户端上的内存使用量? 我正在寻找解决下面问题的东西,但是对于客户端上的javascript . 当我尝试一 ...

  7. linux连接svn上代码,代码管理平台介绍、安装svn、客户端上使用svn(linux)、客户端上使用svn(windows)...

    代码管理平台介绍 代码管理平台介绍--svn 版本控制,记录若干文件内容变化,以便未来查阅特定版本修订状况. 好比某一个业务,须要不断更新,好比产品经理这周提交了产品新的需求,改动了一些代码,咱们把新 ...

  8. 将本地项目上传到Github的两种方式 1.在线上传 2.使用Git客户端上传

    文章目录 注册GitHub账号并创建仓库 上传本地项目到Github的方式一:在线上传 上传本地项目到Github的方式二:使用Git客户端上传 Windows下安装Git客户端 Git配置本地用户名 ...

  9. Mosquitto感知客户端上下线的方法

    欢迎加入QQ群:221779856,国内最活跃的Mosquitto沟通社区,关于MQTT.Mosquitto.IM.推送系统.物联网.高并发处理等技术. 设备上下线的通知不属于mqtt协议的一部分,m ...

  10. Struts提供我们方便地将客户端上传的文件处理

    以下是本人的一些分享,我热爱编程,希望能多交编程的爱好者,如果你也是其中一名,那么请加好友,大家关注一下,下面的文章是自己觉得一些有用的东西,留下来给自己当笔记,当然也希望能帮助到你,首先感谢你的阅读 ...

最新文章

  1. MySQL 备份和恢复策略
  2. html5 2015,2015年有用的16大免费的响应式HTML5框架
  3. 一句话总结.Net下struct和class内存分配方面的区别
  4. oracle中decode的用法(例子)
  5. Python随机函数
  6. 【Android 】零基础到飞升 | ListView简单实用
  7. 小米拒绝权限_手机用户隐私保护升级:小米MIUI 11支持“空信息授权”
  8. 四道Java基础题 你能对几道?
  9. Error: `brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead.
  10. python爬虫常见报错_Python爬虫系列之什么是爬虫
  11. 拍照翻译软件 拍照识别 云脉慧眼
  12. matlab验证费根鲍姆常数,费根鲍姆常数(混沌理论和非线性)
  13. PLC西门子杯比赛,三部十层电梯博图v15.1程序
  14. 如何实现QSV转mp4呢?
  15. U8流程财务段的处理
  16. 使用SSC添加大量的SDO条目
  17. #今日论文推荐# DeepMind将范畴论、抽象代数组合,发现GNN与DP之间的联系
  18. Could not open Selected VM debug port (8700)
  19. KL散度(Divergence)
  20. 艾宾浩斯(H.Ebbinghaus)遗忘曲线

热门文章

  1. IOS音视频(四十五)HTTPS 自签名证书 实现边下边播
  2. 社区价值:福山论自组织、社区、社会资本
  3. 西工大计算机学院优秀毕业生,计算机学院优秀博士毕业生陈穆林:不负时光 不负自己 奋斗的时光是一抹永不褪色记忆...
  4. 扁豆凝集素LCA/LcH填料/小扁豆凝集素-琼脂糖凝胶/双花扁豆凝集素DBA/黑皮扁豆凝集素
  5. 三星手机性能测试软件,Exynos4210处理器性能测试_三星 I9100 GALAXY SII(16GB/黑色)_手机Android频道-中关村在线...
  6. DLang、Rust 以及 Golang 对比数据库操作方式
  7. 驾驭你的“职场布朗运动”--李云
  8. 享元模式(羽量级模式、蝇量级模式Flyweight,对象结构型模式)
  9. c++文件的读取和写入
  10. QQ邮箱搜索器 邮箱地址批量搜索