dart语言第一发:编写一个web app

为了了解sky框架到底是怎么回事,我觉得还是有必要先去了解dart语言,这是官方的教程,我觉得要研究dart语言从这篇文章开始比较合适。

首先从语言的角度来讲dart设计的目的的确是要替代javascript,但是这条路不好走,先要说服开发者,这比登天还难,然后还要说服浏览器厂商的支持,这些厂商大都跟谷歌是敌人,所以第二点比下地狱之后再登天还难。

所以谷歌现在想另辟蹊径,从自已经统治的安卓系统触发,让dart在移动端大显身手,于是就有了sky这个框架。

那么为什么开发者会买账呢?因为他们自称sky解决了安卓流畅度和跨平台的问题。如果这两点都解决了,很难说开发者不会心动(其实如果你是一个合格的开发者,在现在的安卓平台上,即使仍然用java开发流畅度也不是问题)。

以上是我自己的猜想。。。

回到dart语言上来。

什么是dart语言,dart语言是一种被设计成替换Javascript的语言,和Javascript不同的是,他有main函数,在写代码的时候会让你更有编程的感觉。如果说c语言的文件是.c结尾,java文件是.java结尾,php是.php结尾,那么dart文件就是.dart结尾。其实以什么扩展名结尾并不能说明什么,扩展名可以设计成任意的字符串。之所以指出是以.dart结尾是为了让你明白接下来的web app中只有.dart文件中的代码才是属于dart语言的,我不想让一开始大家就把dart和html混为一潭,就像今天都把html5和js混为一潭一样。

把这些概念讲了之后就让我们按照官方的指导来学习如何使用吧。

https://www.dartlang.org/codelabs/darrrt/#step-one

我们只讲window开发环境下的。

第一步 开发环境


下载dart 以及dart编辑器,dart编辑器其实是一个定制版的eclispe。

下载地址(翻墙吧孩子):

win64 

win32 

注意: Dart 编辑器需要java 6以上。

我已经把64位的dart放在了百度网盘 http://pan.baidu.com/s/1bnhMXCr 

下载下来之后解压产生一个dart目录,打开目录:

QQ图片20150507173954.png

点击DartEditor.exe就可以启动编辑器了。

QQ图片20150507152118.jpg

其实到这里已经完成大部分事情了,不过下载64位的dart倒是花了我很长时间,老是下载失败。

下载dart项目的demo

在这里下载 zip文件  one-hour-codelab-master.zip.  解压得到一个one-hour-codelab-master目录,打开如下:

QQ图片20150507174557.png

其中server目录里面的东西还用不着。

darrrt目录下面是6个demo,每一个demo都在上一个基础上增加了一些功能,在学习这些demo的同时也学会了dart的基本语法。

导入demo

在编辑器中 依次File > Open Existing Folder 导入darrrt目录中的内容。

然后就得到了如下的结构:

The files and directories in the darrrt directory.

要点

  • 这几个目录包含了每一步的完整代码。1-blankbadge里面是app的骨架,后面的demo都是从这里开始。6-piratebadge里面是app的最终版本。

  • 每个目录都是一个完整的项目,包含了:

  • packages目录包含了app所依赖的库以及其他文件 

  • pubspec.yaml 和 pubspec.lock 文件that specify package dependencies This project has all the dependencies set up for you. Dart Editor automatically installs the necessary packages.

  • Dart SDK 包括了sdk提供的所有的方法,变量以及类的源代码

  • Referenced Packages 包含了此项目依赖的第三方库的所有方法,变量,类的源代码 。

第二步运行第一个app(skeleton app, app的骨架)

在这一步,打开源码文件,熟悉里面的dart和html代码,然后运行app。

展开1-blankbadge目录

在dart编辑器中,展开1-blankbadge下面的web目录。这个目录包含了piratebadge.css, piratebadge.dart,和 piratebadge.html几个文件:

QQ图片20150508002450.png

piratebadge.html

<html>
  <head>
    <meta charset="utf-8">
    <title>Pirate badge</title>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="piratebadge.css">
  </head>
  <body>
    <h1>Pirate badge</h1>
    
    <div class="widgets">
      TO DO: Put the UI widgets here.
    </div>
    <div class="badge">
      <div class="greeting">
        Arrr! Me name is
      </div>
      <div class="name">
        <span id="badgeName"> </span>
      </div>
    </div>
    <script type="application/dart" src="piratebadge.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

piratebadge.css

body {
  background-color: #F8F8F8;
  font-family: 'Open Sans', sans-serif;
  font-size: 14px;
  font-weight: normal;
  line-height: 1.2em;
  margin: 15px;
}
h1, p {
  color: #333;
}
.widgets {
  padding-bottom: 20pt;
  float: left;
}
.badge {
  border: 2px solid brown;
  border-radius: 1em;
  background: red;
  font-size: 14pt;
  width: 14em;
  height: 7em;
  text-align: center;
  float: left;
  margin-left: 20px;
  white-space: nowrap;
  overflow: hidden;
}
.greeting {
  color: white;
  font-family: sans-serif;
  padding: 0.5em;
}
.name {
  color: black;
  background: white;
  font-family: "Marker Felt", cursive;
  font-size: 25pt;
  padding-top: 1.0em;
  padding-bottom: 0.7em;
  height: 16px;
}
#generateButton {
  font-size: 12pt;
  margin-top: 20px;
}
input\[type="text"\] {
  font-size: 12pt;
  margin-top: 10pt;
  margin-bottom: 10pt;
  width: 12em;
}
@media all and (max-width: 500px) {
  .badge {
    margin-left: 0px;
  }
}

piratebadge.dart

void main() {
  // Your app starts here.
}

除了piratebadge.dart有点特别之外,其他的html和css文件让我们感觉这是在写一个web文件。piratebadge.dart中的main函数是app的入口函数,piratebadge.html中的

可以看到在main函数中啥也没做,不过我们已经搭建起了一个app的基本骨架,后面的项目都是在这上面添砖加瓦了。

运行这个app

虽然运行的结果和一个html组成的网页没有区别,但是我们还是运行一下吧,整个过程感觉怪怪的,我还是第一次体验网页也需要运行才能看结果。。。

直接右键piratebadge.html,然后选择Run in Dartium

Select Run in Dartium

Run in Dartium的意思是在是内置Dart虚拟机的Chrome浏览器(Dartium)中运行,第一次运行需要做一些初始化的工作,因为要链接谷歌api,不翻墙会失败。

运行之后会弹出Dartium,然后在里面显示web app的结果。

QQ图片20150508004452.png

看起来很想一个网页(其实它就是),不过你要是把它做好看点,也可以像app。

你可能已经注意到了,运行有三个选项Run in Dartium, Run as JavaScript, Run on Mobile。Run in Dartium的意思我已经讲了,Run as JavaScript的结果和Run in Dartium差不多,不过弹出的浏览器是默认的普通浏览器,最复杂的是Run on Mobile,在移动端上运行,这才是我想要学习的重点,在另一篇文章中将专门讲解如何在手机上运行。

好了这是第一个项目。

第二部: 添加一个输入框

这一步要做的所有事情都在2-inputnamebadge项目里面,我们直接看它的源码:

css文件就不写了,直接看piratebadge.html和piratebadge.dart

piratebadge.html

<!-- Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
     for details. All rights reserved. Use of this source code is governed by a
     BSD-style license that can be found in the LICENSE file.
-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Pirate badge</title>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="piratebadge.css">
  </head>
  <body>
    <h1>Pirate badge</h1>
    
    <div class="widgets">
      <div>
        <input type="text" id="inputName" maxlength="15">
      </div>
    </div>
    <div class="badge">
      <div class="greeting">
        Arrr! Me name is
      </div>
      <div class="name">
        <span id="badgeName"> </span>
      </div>
    </div>
    <script type="application/dart" src="piratebadge.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

和第一步比较其实就是在类为widgets的div下面添加了一个输入框

piratebadge.dart

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
void  main() {
  querySelector('#inputName').onInput.listen(updateBadge);
}
void updateBadge(Event e) {
  querySelector('#badgeName').text = (e.target as InputElement).value;
}

第一步的main函数是空的,这次有了内容,里面的代码跟Javascript很相似,准确的说很像使用了jQuery的js代码,这就是dart语言了,和Javascript还是有很多不同的。

querySelector('#inputName')表示找到(获取 id=inputName的标签)

 querySelector('#inputName').onInput.listen(updateBadge);

这句话的意思是获取id=inputName的标签并监听其输入事件,输入事件的监听者是updateBadge函数

接下来就是定义updateBadge函数,在updateBadge函数中做了如下事情:

 querySelector('#badgeName').text = (e.target as InputElement).value;

把输入框中的文字赋值给id=badgeName的标签。

其实熟悉jQuery的同学这段代码不用解释 , 一看就懂。

好吧,总算对伊dart有点初步的认识了,的确比Javascript要简单。这种编程风格我也能接受,没有怪异的语法。总之对于已经会java的人来说,没有什么学习成本,唯一的成本可能是需要知道jQuery的选择器是什么东西,毕竟在web

app中dart主要是和html打交道。

后面的每一个项目都是一步一步的添加功能我就不一一讲解了,自己看代码吧。