在這一步中,你需要更改 PirateName 類以實(shí)現(xiàn)從 JSON 文件中獲取名字的列表。這將給你機(jī)會(huì)添加更多的名字進(jìn)程序。
使用File > New File…
創(chuàng)建一個(gè)名為 piratenames.json
含有以下內(nèi)容的 JSON 編碼的文件。
把文件放在 1-blankbadge
你以前寫過(guò)的 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"]}
關(guān)鍵信息
顯示輸入框和按鈕
...
<div>
<input type="text" id="inputName" maxlength="15" disabled>
</div>
<div>
<button id="generateButton" disabled>Aye! Gimme a name!</button>
</div>
...
在文件頂部添加一個(gè) import
import 'dart:html';
import 'dart:math' show Random;
import 'dart:convert' show JSON;
import 'dart:async' show Future;
dart:async
庫(kù)提供異步編程。Future
提供一個(gè)方式在將來(lái)得到一個(gè)值。(對(duì)于 JavaScript 開(kāi)發(fā)者:Futures 和 Promises 一樣。)把 names
和 appellations
替換成這些靜態(tài)的,空的列表。
class PirateName {
...
static List<String> names = [];
static List<String> appellations = [];
...
}
記得從這些聲明中移除 final
。
[ ]
相當(dāng)于 new List()
。
List<String>
。添加兩個(gè)靜態(tài)的方法到 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
關(guān)鍵字標(biāo)記。一個(gè)異步的方法立即返回一個(gè) Future
,所以調(diào)用者在等待方法完成時(shí)有機(jī)會(huì)做其他事。
HttpRequest
用來(lái)檢索來(lái)自 URL 的數(shù)據(jù)時(shí)使用的。
getString()
是一個(gè)方便的方法做一個(gè)簡(jiǎn)單的 GET 請(qǐng)求并返回字符串。
getString()
是異步的,它建立了一個(gè) GET 請(qǐng)求,當(dāng)完成 GET 請(qǐng)求的時(shí)候返回一個(gè) Future
。
await
表達(dá)式,你只可以在異步的方法里使用。執(zhí)行暫停直到 GET 請(qǐng)求完成。(當(dāng) Future
在 getString()
完成時(shí)返回)添加一個(gè)頂級(jí)變量
SpanElement badgeNameElement;
void main() {
...
}
對(duì) main()
函數(shù)做這些更改
void main() {
InputElement inputField = querySelector('#inputName');
inputField.onInput.listen(updateBadge);
genButton = querySelector('#generateButton');
genButton.onClick.listen(generateBadge);
badgeNameElement = querySelector('#badgeName');
...
}
然后添加代碼獲得 JSON 文件里面的名字,同時(shí)處理好異常。
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
關(guān)鍵字了。去除 void
給 main
返回值。異步方法必須返回一個(gè)將來(lái),所以你可以指定返回類型或讓它空白的。readyThePirates()
方法,立即返回一個(gè) Future 。await
關(guān)鍵字執(zhí)行暫停直到將來(lái)完成。readyThePirates()
成功完成返回,設(shè)置界面。try
和 catch
來(lái)檢測(cè)和處理錯(cuò)誤。通過(guò) File > Save All
保存文件。
運(yùn)行應(yīng)用通過(guò)正確點(diǎn)擊 piratebadge.html
,選擇 Run in Dartium
。
如果你想看到應(yīng)用找不到 .json
文件發(fā)生什么,在代碼里改變文件的名字并重新運(yùn)行這個(gè)程序。
把你的應(yīng)用和下面的最終版本對(duì)比一下
http://wiki.jikexueyuan.com/project/learn-dart-in-minutes/images/dart1-learn-dart-in-minutes-step-6-run-the-skeleton-app-pic1.png" alt="dart4" />