版本:v4.0.0+2
在教程的這一部分,你將修改啟動程序來顯示一個英雄的信息。然后你間添加編輯英雄數(shù)據(jù)的能力。完成后,應(yīng)用看起來這樣——在線示例 (查看源碼)。
回顧上一章
在開始編寫代碼之前,讓我們驗(yàn)證你是否有如下的文件結(jié)構(gòu)。如果沒有,回到前一章,查看詳細(xì)介紹。
如果應(yīng)用不運(yùn)行了,啟動應(yīng)用。當(dāng)你做出修改時,通過刷新瀏覽器保持繼續(xù)運(yùn)行。
顯示英雄
為AppComponent
添加兩個屬性:一個表示應(yīng)用名字的title
屬性,和一個表示名為 “Windstorm” 的英雄的hero
屬性。
// lib/app_component.dart (AppComponent class)
class AppComponent {
final title = 'Tour of Heroes';
var hero = 'Windstorm';
}
現(xiàn)在,使用數(shù)據(jù)綁定到這些新屬性,更新@Component
注解中的模板。
// lib/app_component.dart (@Component)
template: '<h1>{{title}}</h1><h2>{{hero}} details!</h2>',
刷新瀏覽器,頁面將顯示標(biāo)題和英雄名字。
雙大括號是 Angular 的插值表達(dá)式語法。這些插值綁定組件的title
和hero
屬性值,作為字符串,插入到 HTML 的標(biāo)題標(biāo)簽中。
更多關(guān)于插值表達(dá)式的內(nèi)容請看顯示數(shù)據(jù)章節(jié)。
創(chuàng)建 Hero 類
英雄需要更多屬性。把hero
從一個字符串字面量轉(zhuǎn)換成一個類。
創(chuàng)建一個具有 id
和 name
屬性的Hero
類。把這些屬性添加到 app_component.dart
文件的頂部附近,僅在 import 語句下面。
// lib/app_component.dart (Hero class)
class Hero {
final int id;
String name;
Hero(this.id, this.name);
}
在AppComponent
類,重構(gòu)組件的 hero
屬性為 Hero
類型,然后以id
為1
、以name
為 “Windstorm”,初始化它。
// lib/app_component.dart (hero property)
Hero hero = new Hero(1, 'Windstorm');
因?yàn)槲覀儼?hero 從一個字符串換成了對象,所以更新模板中的綁定,來引用 hero 的name
屬性。
template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2>',
刷新瀏覽器,頁面將繼續(xù)顯示英雄的名字。
添加多行 HTML 模板
為了顯示英雄的所有屬性,添加一個<div>
來顯示英雄的id
屬性,另一個<div>
來顯示英雄的name
屬性。為了使模板保持可讀性,每個div
獨(dú)自占一行。
// lib/app_component.dart (multi-line strings)
template: '''
<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div><label>name: </label>{{hero.name}}</div>
''',
使應(yīng)用名字可編輯
用戶應(yīng)該能夠在一個<input>
文本框中編輯英雄名字。文本框應(yīng)該既能顯示 應(yīng)用的name
屬性,又能根據(jù)用戶的輸入更新 屬性。
你需要在<input>
表單元素和hero.name
屬性之間雙向數(shù)據(jù)綁定。
使用雙向綁定
重構(gòu)模板中的英雄名字使其看起來如下:
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name">
</div>
[(ngModel)]
是 Angular 語法,綁定hero.name
屬性到文本框。數(shù)據(jù)在兩個方向流動:從屬性到文本框,從文本框又回到屬性。
聲明非核心指令
不幸的是,這樣改變之后,程序立即崩潰了!
模板解析錯誤
如果你刷新瀏覽器,應(yīng)用不會加載。要知道原因,查看pub serve
輸出。模板解析器不能識別ngModel
,AppComponent
解析錯誤:
Error running TemplateGenerator for forms|lib/src/hero_form_component.dart.
Error: Template parse errors:
Can't bind to 'ngModel' since it isn't a known native property or known directive. Please fix typo or add to directives list.
[(ngModel)]="hero.name"
^^^^^^^^^^^^^^^^^^^^^^^
更新 pubspec
angular_forms
庫包含在它自己的包里。在 pubsepc dependencies中添加包:
// {toh-0 → toh-1}/pubspec.yaml
dependencies:
angular: ^4.0.0
+ angular_forms: ^1.0.0
更新 @Component(directives:...)
盡管NgModel
在angular_forms庫中是一個有效的 Angular 指令,但默認(rèn)它不是可用的。
在模板中使用任意 Angular 指令之前,需要在組件的@Component
注解的directives
參數(shù)中列出它們。你可以單獨(dú)的添加指令,或?yàn)榱朔奖闾砑?a target="_blank" rel="nofollow">formDirectives列表(注意新的導(dǎo)入語句):
// lib/app_component.dart (directives)
import 'package:angular_forms/angular_forms.dart';
@Component(
selector: 'my-app',
// ···
directives: const [formDirectives],
)
刷新瀏覽器,應(yīng)用應(yīng)該可用再次運(yùn)行了。你可以編輯英雄名字并且在文本框上方的<h2>
中立刻看到變化的反應(yīng)。
你已走過的路
來盤點(diǎn)一下都構(gòu)建了哪些內(nèi)容。
- 英雄指南應(yīng)用使用雙大括號插值表達(dá)式(單向數(shù)據(jù)綁定的一種形式)來顯示應(yīng)用的標(biāo)題和
Hero
對象的屬性。 - 使用 Dart 模板字符串寫了一個多行模板,使模板更有可讀性。
- 使用內(nèi)置的
ngModel
指令為<input>
元素添加雙向數(shù)據(jù)綁定。這種綁定既可以顯示英雄的名字又允許用戶修改它。 - 添加formDirectives到應(yīng)用的
@Component
注解的directives
參數(shù),以使 Angular 知道ngModel
是在哪里定義i的。
你的應(yīng)用看起來應(yīng)該這樣——在線示例 (查看源碼)
完整的app_component.dart
是這樣的:
// lib/app_component.dart
import 'package:angular/angular.dart';
import 'package:angular_forms/angular_forms.dart';
@Component(
selector: 'my-app',
template: '''
<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name">
</div>
''',
directives: const [formDirectives],
)
class AppComponent {
final title = 'Tour of Heroes';
Hero hero = new Hero(1, 'Windstorm');
}
class Hero {
final int id;
String name;
Hero(this.id, this.name);
}
下一步