Table of Contents
前言
Dart 是谷歌在 2011 年推出的编程语言,是一种结构化 Web 编程语言,允许用户通过 Chromium 中所整合的虚拟机(Dart VM)直接运行 Dart 语言编写的程序,免去了单独编译的步骤。以后这些程序将从 Dart VM 更快的性能与较低的启动延迟中受益。Dart 从设计之初就为配合现代 web 整体运作而考虑,开发团队也同时在持续改进 Dart 向 JavaScript 转换的快速编译器。Dart VM 以及现代 JavaScript 引擎(V8 等)都是 Dart 语言的首选目标平台。
本教程是 Dart 官方文档 Learn Dart in Minutes 的中文翻译版本。
适用人群
本教程设计为了让对 Dart 感兴趣的软件专业人士简单方便地开始。完成这个教程,你将充分了解 Dart 让自己获得更高的水平的专业知识。
学习前提
在你继续本教程之前,你必须对简单的术语有一定的了解,比如源码,文档等等。因为在你的组织下处理各级软件项目,如果你有软件工作的知识在软件开发和软件测试流程那是最好的。
1
步骤 0:环境搭建
在这一步里,你需要下载 Dart 和示例代码。
获取 Dart
如果你还没获取 Dart,去下载下来并解压缩 zip 文件, 然后会得到一个名为 dart 的文件夹。(更多信息请访问下载页)
提示:Dart编辑器需要Java 6或更高版本支持。有疑问?请查看 Dart 编辑器问题处理页面。
运行编辑器
打开 dart 文件夹并双击 Dart-Editor。
有疑问?请查看 Dart 编辑器问题处理页面。
获取示例代码
用以下方式从 one-hour-codelab GitHub repo 获取示例代码:
- 下载 zip 文件,one-hour-codelab-master.zip。解压缩 ZIP 文件,得到一个名为 one-hour-codelab-master 的文件夹。
- Clone 版本库。 例如,在命令行输入以下命令:
% git clone https://github.com/dart-lang/one-hour-codelab.git
这将会创建一个名为 one-hour-codelab 的文件夹。
打开 one-hour-codelab 示例
在 Dart 编辑器中,使用 File > Open Existing Folder... 来打开 one-hour-codelab 下面的 darrrt 文件夹。
图片 1.1 pic1
提示:如果你在文件名左边看到红色的叉叉或者 packages 目录丢失,说明软件包没有安装好。右击 pubspec.yaml 并选择 Pub Gut。
关键信息
- 几个带序号的目录包含了每一步骤的完整代码。1-blankbadge 包含了最基本的框架版 App,你可以从这开始学习。6-piratebadge 包含了最终版本的 App。
- 每一个带序号的目录都包含了一个完整的项目,他们包括:
- 一个 packages 目录,包含类库和 App 运行时依赖的其它文件
- pubspec.yaml 和 pubspec.lock 文件,指定了包的依赖。这个项目已经为你设置好了所有的依赖。Dart 编辑器会自动安装所需的包。
- Dart SDK 包含了由Dart软件开发包提供的所有方法、变量和类的源代码。
- Referenced Packages 包含了应用所依赖的附加类库的所有方法、变量和类的源代码。
2
步骤 1:运行一个框架应用
在这一步中,你打开源文件,熟悉你自己的 Dart 和 HTML 代码,然后运行这个 App。
新建一个 1-blankbadge 目录
在Dart编辑器中,点击 1-blankbadge
下 web
目录左边的小箭头,展开 web
目录。这个目录包含一个 piratebadge.css
文件,一个 piratebadge.dart
,和一个 piratebadge.html
文件。
打开文件
在Dart编辑器中,通过双击文件名来打开 piratebadge.dart
文件和 piratebadge.html
文件
查看代码
熟悉一下这个框架应用的 HTML 和 Dart 代码。
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.html
文件的所有更改都是在 class
为 widgets
的 <div>
标签中进行的。 - 在后续步骤中, id
为 badgeName
的 <span>
标签会被具有用户输入功能的Dart代码升级。 - 第一个 <script>
标签引入了一个主文件,piratebadge.dart
文件。 - Dart 虚拟机可以原生地运行 Dart 代码。 Dart 虚拟机会在 Dartium 中构建--一个特殊的,可以让你运行Dart App的 Chromium 浏览器。
- packages/browser/dart.js
脚本会检查原生Dart支持,同时引导Dart虚拟机载入编译JavaScript脚本。
piratebadge.dart
void main() {
// 你的应用从这里开始
}
关键信息:
- 这个文件包含一个程序的入口 main() 方法. 在 piratebadge.html
文件的 <script>
标签会通过运行这个方法来开始应用。 - main() 方法是一个 top-level
的方法。 - 一个 top-level
的变量或者方法是在类外进行公开定义的
运行这个应用
在Dart编辑器中运行一个应用:右击 piratebadge.html
文件然后选择 Run in Dartium
。
图片 2.1 运行
Dart 编辑器启动了 Dartium,在构建之后,读取到了 piratebadge.html
文件。 piratebadge.html
文件启动了这个应用并且调用了main()方法。
你应该看到如下结果。
图片 2.2 运行
3
步骤 2:添加一个输入框
在这一步中,你将在你的 App 中添加一个输入框。作为一个用户文本输入框,Dart可以从中取得一个值。
编辑 piratebadge.html
在 class 为 widgets 的 <div>
中添加一个 <input>
标签。
...
<div class="widgets">
<div>
<input type="text" id="inputName" maxlength="15">
</div>
</div>
...
- <input>
标签的 id 是 inputName
。Dart 使用 #inputName
的 CSS 选择器从 DOM 中选择这个元素
编辑 piratebadge.dart
在文件的顶部引入 dart:html
库。
import 'dart:html';
- 这里从 dart:html
引入了所有的类和其他资源。 - 不要担心臃肿的代码。构建程序会帮你进一步简化代码。
- dart:html
库包含了所有DOM元素类型。 - 一会儿你将会使用一些关键字来导入一些特殊的库。
- Dart 编辑器会提示你导入的库是未被使用的,没关系,下一步我们就会修复它。
添加一个方法来监听输入框
void main() {
querySelector('#inputName').onInput.listen(updateBadge);
}
- 在 dart:html
中定义的 querySelector()
方法,获取到了指定的 DOM。这里,通过#inputName选择器获取到了指定的输入框。 - querySelector()
方法的返回值是一个 DOM 元素。 - 鼠标和键盘事件被存放在一个流中。
- 提供一个异步的流数据序列。使用 listen()
方法,可以从流中得到安全的数据。 - onInput.listen()
监听到了输入框的流事件。当监听到时,updateBadge()
方法被调用。 - 当用户按下一个键时,将产生一个事件。
- 你可以用单引号或双引号来创建一个字符串。
- Dart 编辑器提示你有个方法没有被创建,让我们来解决它。
用一个 top-level
级别的方法来实现一个事件方法。
...
void updateBadge(Event e) {
querySelector('#badgeName').text = e.target.value;
}
- 这个函数将 badgename
元素的值设置成文本输入字段的值。 - 事件 e
是 updateBadge
函数的参数. 这个参数的名字是 e
;类型是一个 Event
修复警告信息
...
void updateBadge(Event e) {
querySelector('#badgeName').text = (e.target as InputElement).value;
}
- 在这个例子中,e.target
是产生事件的输入源。
运行应用
保存你的文件
右击 piratebadge.html
选择 Run in Dartium
。
和下面的示例比较一下。
图片 3.1 运行
4
步骤 3:添加一个按钮
在这一步中,你将添加一个按钮。应用启用时,文本字段中没有文本。用户单击按钮时,应用将显示出 Anne Bonney 的字样。
编辑 piratebadge.html
...
<div class="widgets">
<div>
<input type="text" id="inputName" maxlength="15">
</div>
<div>
<button id="generateButton">Aye! Gimme a name!</button>
</div>
</div>
...
- 按钮有一个 ID 叫做 generateButton
,所以Dart可以找到它。
编辑 piratebadge.dart
import 'dart:html';
ButtonElement genButton;
- 按钮元素是 dart:html
中众多元素的一个。 - 变量,包括数字,如果没有实质内容,就为null。
void main() {
querySelector('#inputName').onInput.listen(updateBadge);
genButton = querySelector('#generateButton');
genButton.onClick.listen(generateBadge);
}
- 注册一个 click
事件
...
void setBadgeName(String newName) {
querySelector('#badgeName').text = newName;
}
- 这个方法更新了 HTML 页面
为按钮实现一个点击监听
...
void generateBadge(Event e) {
setBadgeName('Anne Bonney');
}
- 这个方法将 badgeName
的显示内容设置为了 Anne Bonney 。
修改 updateBadge()
方法,在其中调用 setBadgeName()
方法
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
setBadgeName(inputName);
}
- 将文本框输入的值赋值给一个本地 String 变量
在 updateBadge()
方法中添加一个 if-else 结构
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
setBadgeName(inputName);
if (inputName.trim().isEmpty) {
// To do: add some code here.
} else {
// To do: add some code here.
}
}
- String
来源于 dart:core
库,这个库在每一个 Dart程序中都被自动添加。 - Dart 拥有公共的语言结构,例如 if-else
。
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
setBadgeName(inputName);
if (inputName.trim().isEmpty) {
genButton..disabled = false
..text = 'Aye! Gimme a name!';
} else {
genButton..disabled = true
..text = 'Arrr! Write yer name!';
}
}
- updateBadge()
的代码在按钮元素上使用 cascade 操作。其结果和下面代码结果一样
genButton.disabled = false;
genButton.text = 'Aye! Gimme a name!';
运行应用
保存你的文件
右击 piratebadge.html
选择 Run in Dartium
。
和下面的实际比较一下。
图片 4.1 运行
5
步骤 4:创建一个 PirateName 的类
在这一步中,你改变的仅是 Dart 的代码,你可以自己为你新建的类起个名字,当创建这个类的一个实例,随机选择一个名字和称谓,或者你可以提供一个名字和称谓给构造函数。
编辑 piratebadge.dart
在文件的顶部加入 import
import 'dart:html';
import 'dart:math' show Random;
piratebadge.dart
关键信息
- 使用 show
关键字,你可以只导入你需要的类,方法,和属性。 - Random
提供了一个随机数的发生器。
加入一个类的声明在在文件的底部
...
class PirateName {
}
- 这个类的声明给类提供一个名字
创建一个类级别的 Random 实体
class PirateName {
static final Random indexGen = new Random();
}
- static
定义类级别的字段,就是说随机数发生器被所有的类实例共享。 - Dart 编辑器强调静态名字。
- 使用 new
调用一个构造函数。
在类中加入两个成员变量,一个定义 first name ,一个定义 appellation 。
class PirateName {
static final Random indexGen = new Random();
String _firstName;
String _appellation;
}
- 私有变量用(_).
强调。Dart 没有 private 关键字。
在类内创建两个静态的 List ,提供 names 和 appellations 两个集合供选择。
class PirateName {
...
static final List names = [
'Anne', 'Mary', 'Jack', 'Morgan', 'Roger',
'Bill', 'Ragnar', 'Ed', 'John', 'Jane' ];
static final List appellations = [
'Jackal', 'King', 'Red', 'Stalwart', 'Axe',
'Young', 'Brave', 'Eager', 'Wily', 'Zesty'];
}
- final
修饰的变量不能更改。 - 列表是 Dart 内置的,使用 List 来创建。
- List 类提供 API 给列表。
给类提供一个构造函数。
class PirateName {
...
PirateName({String firstName, String appellation}) {
if (firstName == null) {
_firstName = names[indexGen.nextInt(names.length)];
} else {
_firstName = firstName;
}
if (appellation == null) {
_appellation = appellations[indexGen.nextInt(appellations.length)];
} else {
_appellation = appellation;
}
}
}
- 构造函数名和类名相同。
- 参数被包含在花括号 ({ })
是可选的被命名的参数。 - nextInt()
函数得到一个随机整数从随机数发生器里。 - 使用方括号 ([ ])
为列表添加索引。 - 使用 length
属性返回列表中元素的个数。 - 代码使用随机数作为列表的索引。
提供一个 getter
给私有字段。
class PirateName {
...
String get pirateName =>
_firstName.isEmpty ? '' : '$_firstName the $_appellation';
}
- Getters 是一个特别的方法,提供访问对象的属性。
- 三元运算符 ?:
是 if-then-else
语句的简略写法。 - 字符串插入 ('$_firstName the $_appellation')
让我们很容易从其他对象构建字符串。 - 大箭头 ( => expr; )
是 { return expr; }
语法的一个简称。
重写 toString()
方法。
class PirateName {
...
String toString() => pirateName;
}
- 因为对象实现 toString()
方法没有给很多的信息,很多类重写 toString()
。 - 当你调用 print(anObject)
得到字符串,返回值是 anObject.toString()
得到的。 - 重写 toString()
在的调试和输出的时候特别有用。
修改 setBadgeName()
方法,使用 PirateName 而不是 String 。
void setBadgeName(PirateName newName) {
querySelector('#badgeName').text = newName.pirateName;
}
- 代码调用 getter 得到 PirateName 作为一个字符串。
更改 updateBadge()
基于输入字段的值生成 PirateName 。
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
setBadgeName(new PirateName(firstName: inputName));
...
}
- 调用构造函数给可选的命名参数提供一个值。
更改 generateBadge()
生成一个 PirateName 而不是使用 Anne Bonney
。
void generateBadge(Event e) {
setBadgeName(new PirateName());
}
- 在这种情况下,通过无参数调用构造函数。
运行应用
使用 File > Save All
保存。
运行应用正确点击 piratebadge.html
并选择 Run in Dartium
。
把你的应用和下面的比较。
在输入框中输入。删除输入字段。点击按钮。
图片 5.1 dart4
6
步骤 5:保存到本地存储
在这一步中,你给应用一些持久性通过把标记的名字保存到本地存储当它每次改变时。当你重启应用时它初始化标记,从保存的名字里。
编辑 piratebadge.dart
从 dart:convert
库里导入 JSON 转化器。
import 'dart:html';
import 'dart:math' show Random;
import 'dart:convert' show JSON;
关键信息
- JSON
提供了方便的访问最常见的 JSON 的用例。
给 PirateName 类添加一个命名的构造函数。
class PirateName {
...
PirateName.fromJSON(String jsonString) {
Map storedName = JSON.decode(jsonString);
_firstName = storedName['f'];
_appellation = storedName['a'];
}
}
- 构造函数创建一个新的 PirateName 实例来自 JSON 编码的字符串。
- PirateName.fromJSON
是一个命名的构造函数。 - JSON.decode()
解析 JSON 字符串并由此创建一个 Dart 对象。 - pirate name
解析成一个 Map
对象。
添加 getter 给 PirateName 类,编码 pirate name 在 JSON 字符串中。
class PirateName {
...
String get jsonString => JSON.encode({"f": _firstName, "a": _appellation});
}
- getter 使用 map 格式化 JSON 字符串。
声明一个顶级字符串。
final String TREASURE_KEY = 'pirateName';
void main() {
...
}
- 你保存键值对到本地存储,这个字符串是键,pirate name
是值。
当标记的名字更改时保存标记的 pirate name
。
void setBadgeName(PirateName newName) {
if (newName == null) {
return;
}
querySelector('#badgeName').text = newName.pirateName;
window.localStorage[TREASURE_KEY] = newName.jsonString;
}
- 本地存储通过浏览器窗口提供。
添加一个顶级函数 getBadgeNameFromStorage()
。
void setBadgeName(PirateName newName) {
...
}
PirateName getBadgeNameFromStorage() {
String storedName = window.localStorage[TREASURE_KEY];
if (storedName != null) {
return new PirateName.fromJSON(storedName);
} else {
return null;
}
}
- 这个方法从本地存储检索 pirate name
并且由此创建一个 PirateName 对象。
通过 main()
函数调用方法。
void main() {
...
setBadgeName(getBadgeNameFromStorage());
}
- 从本地存储中初始化标记的名字。
运行应用
通过 File > Save All
保存文件。
运行应用通过正确点击 piratebadge.html
,选择 Run in Dartium
。
把你的应用和下面正在运行的进行比较。
点击放一个名字进标记。重新运行这个应用会看到你写的名字。
图片 6.1 dart4
7
步骤 6:从 JSON 编码的文件里读取名字
在这一步中,你需要更改 PirateName 类以实现从 JSON 文件中获取名字的列表。这将给你机会添加更多的名字进程序。
创建 piratenames.json
使用File > New File…
创建一个名为 piratenames.json
含有以下内容的 JSON 编码的文件。 把文件放在 1-blankbadge
你以前写过的 Dart 和 HTML 文件的旁边。
{ "names": [ "Anne", "Bette", "Cate", "Dawn",
"Elise", "Faye", "Ginger", "Harriot",
"Izzy", "Jane", "Kaye", "Liz",
"Maria", "Nell", "Olive", "Pat",
"Queenie", "Rae", "Sal", "Tam",
"Uma", "Violet", "Wilma", "Xana",
"Yvonne", "Zelda",
"Abe", "Billy", "Caleb", "Davie",
"Eb", "Frank", "Gabe", "House",
"Icarus", "Jack", "Kurt", "Larry",
"Mike", "Nolan", "Oliver", "Pat",
"Quib", "Roy", "Sal", "Tom",
"Ube", "Val", "Walt", "Xavier",
"Yvan", "Zeb"],
"appellations": [ "Awesome", "Captain",
"Even", "Fighter", "Great", "Hearty",
"Jackal", "King", "Lord",
"Mighty", "Noble", "Old", "Powerful",
"Quick", "Red", "Stalwart", "Tank",
"Ultimate", "Vicious", "Wily", "aXe", "Young",
"Brave", "Eager",
"Kind", "Sandy",
"Xeric", "Yellow", "Zesty"]}
关键信息
- 文件包含 JSON 编码的 map ,它包含两个字符串列表。
编辑 piratebadge.html
显示输入框和按钮
...
<div>
<input type="text" id="inputName" maxlength="15" disabled>
</div>
<div>
<button id="generateButton" disabled>Aye! Gimme a name!</button>
</div>
...
- Dart 代码启用输入框和按钮,然后名字成功从 JSON 文件中读出来。
编辑 piratebadge.dart
在文件顶部添加一个 import
import 'dart:html';
import 'dart:math' show Random;
import 'dart:convert' show JSON;
import 'dart:async' show Future;
- dart:async
库提供异步编程。 - Future
提供一个方式在将来得到一个值。(对于 JavaScript 开发者:Futures 和 Promises 一样。)
把 names
和 appellations
替换成这些静态的,空的列表。
class PirateName {
...
static List<String> names = [];
static List<String> appellations = [];
...
}
- 记得从这些声明中移除 final
。 - [ ]
相当于 new List()
。 - List 是一个通用的类型- List 可以包含任何类型的对象。如果你打算让一个列表只包含字符串,你可以把它声明成为 List<String>
。
添加两个静态的方法到 PirateName 类:
class PirateName {
...
static Future readyThePirates() async {
String path = 'piratenames.json';
String jsonString = await HttpRequest.getString(path);
_parsePirateNamesFromJSON(jsonString);
}
static _parsePirateNamesFromJSON(String jsonString) {
Map pirateNames = JSON.decode(jsonString);
names = pirateNames['names'];
appellations = pirateNames['appellations'];
}
}
- readyThePirates
被 async
关键字标记。一个异步的方法立即返回一个 Future
,所以调用者在等待方法完成时有机会做其他事。 - HttpRequest
用来检索来自 URL 的数据时使用的。 - getString()
是一个方便的方法做一个简单的 GET 请求并返回字符串。 - getString()
是异步的,它建立了一个 GET 请求,当完成 GET 请求的时候返回一个 Future
。 - await
表达式,你只可以在异步的方法里使用。执行暂停直到 GET 请求完成。(当 Future
在 getString()
完成时返回) - GET 请求返回 JSON 字符串之后,代码从字符串中提取私有名字和称谓。
添加一个顶级变量
SpanElement badgeNameElement;
void main() {
...
}
- 存储 span 元素以便重复使用,而不是从 DOM 里重复查询它。
对 main()
函数做这些更改
void main() {
InputElement inputField = querySelector('#inputName');
inputField.onInput.listen(updateBadge);
genButton = querySelector('#generateButton');
genButton.onClick.listen(generateBadge);
badgeNameElement = querySelector('#badgeName');
...
}
- 在全局变量存储这些 span 元素,同时在局部变量里存储 input 元素。
然后添加代码获得 JSON 文件里面的名字,同时处理好异常。
main() async {
...
try {
await PirateName.readyThePirates();
//on success
inputField.disabled = false; //enable
genButton.disabled = false; //enable
setBadgeName(getBadgeNameFromStorage());
} catch (arrr) {
print('Error initializing pirate names: $arrr');
badgeNameElement.text = 'Arrr! No names.';
}
}
- async
修饰方法体,这样方法就可以 async
关键字了。去除 void
给 main
返回值。异步方法必须返回一个将来,所以你可以指定返回类型或让它空白的。 - 调用 readyThePirates()
方法,立即返回一个 Future 。 - 使用 await
关键字执行暂停直到将来完成。 - 当 将来通过 readyThePirates()
成功完成返回,设置界面。 - 使用 try
和 catch
来检测和处理错误。
运行应用
通过 File > Save All
保存文件。
运行应用通过正确点击 piratebadge.html
,选择 Run in Dartium
。
如果你想看到应用找不到 .json
文件发生什么,在代码里改变文件的名字并重新运行这个程序。 把你的应用和下面的最终版本对比一下
图片 7.1 dart4
8
步骤 7:构建并运行 App
在这步中,你将使用 pub build 来生成 App 的资源并将他们放入一个名为 build 的新目录中。除了其它任务之外,构建过程中还会生成最精简的 JavaScript 代码,这些代码可以在现在任何主流的浏览器中运行。
需要注意的是 one-hour-codelab 目录包含几个目录,分别对应每个步骤,他们都被当做 one-hour-codelab 应用的一部分。构建过程为每个目录生成了资源。每个目录都可以被单独部署。
检出 pubspec.yaml
右击打开 pubspec.yaml。单击编辑窗口底部的 Source 标签。
name: avast_ye_pirates
description: Write a Dart web app code lab
dependencies:
browser: any
关键信息
- 目录中的 pubspec.yaml 文件标识了这个目录和其中的内容是一个应用。
- pubspec.yaml 提供了应用的元信息,例如它的名字。
- pubspec.yaml 同时也列出了应用所依赖的库。 这个 App 需要的 browser 库被托管在了 pub.dartlang.org 上面,同时还托管了许多其它的库。
- any 代表选择符合你SDK的最新的软件包。
查看包目录
在 Dart 编辑器中,展开 1-blankbadge 下的 packages 目录。
图片 8.1 pic1
关键信息
- packages 目录包含了 pubspec.yaml 文件中列出的所有依赖的代码。他们是 Dart 编辑器自动安装的。
- browser 包包含了检查本地 Dart 支持的 dart.js 脚本。
- 为了能让应用成功部署,这些包必须包含在构建的应用中。
运行 Pub 构建
选择 pubspec.yaml,然后选择 **Tools > Pub Build - Minified,将会构建 one-hour-codelab 目录下的所有东西。输入内容类似如下:
Loading source assets...
Building avast_ye_pirates...
[Info from Dart2JS]:
Compiling avast_ye_pirates|web/piratebadge.dart...
[Info from Dart2JS]:
Took 0:00:08.671410 to compile avast_ye_pirates|web/piratebadge.dart.
Built 6 files to "build".
关键信息
- pub build 命令创建了一个 build 目录
- 你可以选择 Pub Build - Minified 或者 Pub Build - Debug。 当构建一个最精简的 JavaScript 时,所有空格和无关的字符都会被移动,创建一个更紧凑的文件,但它的可读性更低。
- build 目录包含了部署项目所需要的一切东西。
查看 build 目录
在你工作的 1-blankbadge 目录下,展开 build 目录,然后展开 web 目录。
图片 8.2 pic2
关键信息
- build/web 包含了 App 单独部署所需的所有文件。
- piratebadge.dart.js 是一个精简的 JavaScript 文件。 当部署时,这个文件会运行在浏览器中。
运行 App
关键信息
- App 运行在本机上。如果你想共享给他人,你需要将你的 App 部署到主机上。
9
下面要做什么?
现在你已经写完你的 App 了,下面要做什么呢?以下是一些建议。
搭建一台服务器并部署你的 App
server side code lab 允许在 RESTful 的服务器上通过存储海盗名字来创建一个海盗船员。
同样的,如果你对服务端编程感兴趣,可以查看 Write HTTP Clients & Servers 教程。
检出示例
在线运行一些 Dart 程序并检出 Sample Page 上的示例代码。
阅读教程
从 Dart tutorials 中学到更多关于 Dart 的知识。
10
总结和资源
想想你已经完成的
这个代码实验室提供了大多数的 Dart 语言特性和许多库的特性概览。想学习更多的话请参考以下资源。
Dart 语言
A Tour of the Dart Language 介绍了如何使用 Dart 基本特性,从变量和运算符到类和库。这个代码实验室介绍了 Dart 的以下特性,这些特性在语言概览中都有详细介绍。
- 字符串插值 ('$_firstName the $_appellation'
) - 级联运算符 (..
) - 胖箭头 (=>
) 函数语法 - 三目运算符 (?:
) - 命名构造函数 (PirateName.fromJSON(...)
( - 可选参数
- 类
- getters
- 实例方法和属性
- 类方法和属性
- 顶级变量和函数
- 用 as 做类型转换 ((e.target as InputElement)
) - 导入,带 show 的导入 (import 'dart:math' show Random;
) - 泛型
- 异步支持(async and await
)
在线文档
Dart 库
- A Tour of the Dart Language 介绍了如何使用 Dart 库的基本特性。
类的API文档
- String, List, Map, Random, InputElement, ButtonElement, Event, HttpRequest, Future 和 Stream
库的API文档
JSON和本地存储的API文档
反馈
请到 GitHub 上的 dartlang repo 提供反馈
更多信息请访问




