AngularDart4.0 指南- 表单
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
表單是商業(yè)應(yīng)用程序的主流。您可以使用表單登錄,提交幫助請(qǐng)求,下訂單,預(yù)訂航班,安排會(huì)議,并執(zhí)行無數(shù)其他數(shù)據(jù)錄入任務(wù)。
在開發(fā)表單時(shí),創(chuàng)建一個(gè)數(shù)據(jù)錄入體驗(yàn)非常重要,該體驗(yàn)可以通過工作流高效地引導(dǎo)用戶。
開發(fā)表單需要設(shè)計(jì)技巧(超出本頁面的范圍),以及雙向數(shù)據(jù)綁定,更改跟蹤,驗(yàn)證和錯(cuò)誤處理的框架支持,您將在本頁面上了解這些信息。
本頁面向您展示了如何從頭構(gòu)建一個(gè)簡單的表單。一路上你將學(xué)習(xí)如何:
- 用組件和模板構(gòu)建一個(gè)Angular表單。
- 使用ngModel創(chuàng)建讀取和寫入輸入控制值的雙向數(shù)據(jù)綁定。
- 跟蹤狀態(tài)變化和表單控件的有效性。
- 使用跟蹤控件狀態(tài)的特殊CSS類提供視覺反饋。
- 向用戶顯示驗(yàn)證錯(cuò)誤并啟用/禁用表單控件。
- 使用模板引用變量在HTML元素之間共享信息。
您可以在Plunker中運(yùn)行實(shí)例(查看源代碼)并從那里下載代碼。
模板驅(qū)動(dòng)的形式
您可以通過使用本頁中描述的特定于表單的指令和技術(shù)在Angular模板語法中編寫模板來構(gòu)建表單。
您也可以使用響應(yīng)式(或模型驅(qū)動(dòng))方法來構(gòu)建表單。 但是,此頁面重點(diǎn)介紹模板驅(qū)動(dòng)的表單。
您可以使用Angular模板 構(gòu)建幾乎任何表單- 登錄表單,聯(lián)系表單和幾乎任何業(yè)務(wù)表單。 您可以創(chuàng)造性地設(shè)計(jì)控件,將它們綁定到數(shù)據(jù),指定驗(yàn)證規(guī)則和顯示驗(yàn)證錯(cuò)誤,有條件地啟用或禁用特定控件,觸發(fā)內(nèi)置的視覺反饋等等。
Angular通過許多重復(fù)的,模板化的任務(wù)使處理過程變得簡單。
您將學(xué)習(xí)如何構(gòu)建一個(gè)模板驅(qū)動(dòng)的表單,如下所示:
英雄就業(yè)機(jī)構(gòu)使用這種形式來維護(hù)關(guān)于英雄的個(gè)人信息。 每個(gè)英雄都需要一份工作。 讓正確的英雄與正確的危機(jī)相匹配是公司的使命。
這個(gè)表格中的三個(gè)字段中的兩個(gè)是必需的。 遵循材料設(shè)計(jì)準(zhǔn)則,必填字段帶有星號(hào)(*)。
如果您刪除了英雄名稱,表單將以吸引人注意的風(fēng)格顯示驗(yàn)證錯(cuò)誤:
請(qǐng)注意提交按鈕被禁用,并且輸入控件從綠色變?yōu)榧t色。
您將以小步驟構(gòu)建此表單:
建立
按照設(shè)置說明創(chuàng)建一個(gè)名為表單的新項(xiàng)目。
添加angular_forms
Angular表單功能位于angular_forms庫中,該庫位于其自己的包中。 將該包添加到pubspec依賴項(xiàng):
創(chuàng)建一個(gè)模型
當(dāng)用戶輸入表單數(shù)據(jù)時(shí),您將捕獲其更改并更新模型的實(shí)例。 直到你知道模型是什么樣子,你才能布置表格。
一個(gè)模型可以像“錢包”一樣簡單,掌握關(guān)于應(yīng)用程序重要事實(shí)的事實(shí)。 這很好地描述了英雄類與三個(gè)必填字段(id, name, power)和一個(gè)可選字段(alterEgo)。
在lib目錄中,使用給定的內(nèi)容創(chuàng)建以下文件:lib/src/hero.dart
class Hero {int id;String name, power, alterEgo;Hero(this.id, this.name, this.power, [this.alterEgo]);String toString() => '$id: $name ($alterEgo). Super power: $power'; }這是一個(gè)缺乏要求,沒有行為的雞肋模型,對(duì)于演示來說足夠了。
alterEgo是可選的,所以構(gòu)造函數(shù)可以讓你忽略它。 請(qǐng)注意[this.alterEgo]中的括號(hào)。
你可以像這樣創(chuàng)建一個(gè)新的英雄:
var myHero = new Hero(42, 'SkyDog', 'Fetch any object at any distance', 'Leslie Rollover'); print('My hero is ${myHero.name}.'); // "My hero is SkyDog."創(chuàng)建一個(gè)基本的表單
一個(gè)Angular表單有兩個(gè)部分:一個(gè)基于HTML的模板和一個(gè)組件類,以編程方式處理數(shù)據(jù)和用戶交互。 從課程開始,因?yàn)樗喴卣f明了英雄編輯可以做什么。
創(chuàng)建一個(gè)表單組件
使用給定的內(nèi)容創(chuàng)建以下文件:lib/src/hero_form_component.dart (v1)
import 'package:angular/angular.dart'; import 'package:angular_forms/angular_forms.dart';import 'hero.dart';const List<String> _powers = const ['Really Smart','Super Flexible','Super Hot','Weather Changer' ];@Component(selector: 'hero-form',templateUrl: 'hero_form_component.html',directives: const [CORE_DIRECTIVES, formDirectives], ) class HeroFormComponent {Hero model = new Hero(18, 'Dr IQ', _powers[0], 'Chuck Overstreet');bool submitted = false;List<String> get powers => _powers;void onSubmit() => submitted = true; }這個(gè)組件沒有什么特別之處,沒有任何特定的形式,沒有什么區(qū)別它與你之前寫的任何組件。
理解這個(gè)組件只需要前面幾頁中介紹的Angular概念。
- 代碼導(dǎo)入您剛創(chuàng)建的主Angular庫和Hero模型。
- hero-form的@Component選擇器值意味著您可以使用<hero-form>元素將此表單放在父模板中。
- templateUrl屬性指向模板HTML的單獨(dú)文件(您將很快創(chuàng)建)。
- 您為model和power定義了模擬數(shù)據(jù)。
順便說一句,您可以注入數(shù)據(jù)服務(wù)來獲取和保存真實(shí)數(shù)據(jù),或者將這些屬性作為輸入和輸出(請(qǐng)參閱“模板語法”頁面中的輸入和輸出屬性)來綁定到父組件。 這不是現(xiàn)在的問題,這些未來的變化不會(huì)影響表單。
修改應(yīng)用程序組件
AppComponent是應(yīng)用程序的根組件。 它將承載HeroFormComponent。
將初學(xué)者應(yīng)用版本的內(nèi)容替換為以下內(nèi)容:lib/app_component.dart
import 'package:angular/angular.dart';import 'src/hero_form_component.dart';@Component(selector: 'my-app',template: '<hero-form></hero-form>',directives: const [HeroFormComponent], ) class AppComponent {}創(chuàng)建一個(gè)初始表單模板
使用以下內(nèi)容創(chuàng)建模板文件:lib/src/hero_form_component.html (start)
<div class="container"><h1>Hero Form</h1><form><div class="form-group"><label for="name">Name *</label><input type="text" class="form-control" id="name" required></div><div class="form-group"><label for="alterEgo">Alter Ego</label><input type="text" class="form-control" id="alterEgo"></div><div class="row"><div class="col-auto"><button type="submit" class="btn btn-primary">Submit</button></div><small class="col text-right">* Required</small></div></form> </div>該語言只是HTML5。 您將展示兩個(gè)Hero字段,name和alterEgo,并在輸入框中將其打開以供用戶輸入。
Name <input>控件具有HTML5必需屬性; Alter Ego <input>控件什么也不做,因?yàn)?span style="color:#008000;">alterEgo是可選的。
您在底部添加了一個(gè)提交按鈕,其中有一些類用于樣式。
你還沒有使用Angular。 沒有綁定或額外的指令,只是布局。
在模板驅(qū)動(dòng)的表單中,如果已經(jīng)導(dǎo)入了angular_forms庫,則不必為了使用庫功能而對(duì)<form>標(biāo)記執(zhí)行任何操作。 繼續(xù)看看這是如何工作的。
刷新瀏覽器。 你會(huì)看到一個(gè)簡單的,沒有樣式的表單。
表單的樣式
一般的CSS類container和btn來自Bootstrap。 Bootstrap還具有form-specific的類,包括form-control和form-group。 一起,這些給表單了一些樣式。
Angular可不使用Bootstrap類或任何外部庫的樣式。 Angular的應(yīng)用程序可以使用任何CSS庫或不使用。
通過將以下鏈接插入到index.html的<head>中來添加Bootstrap樣式:web/index.html (bootstrap)
<link rel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"crossorigin="anonymous">刷新瀏覽器。 你會(huì)看到一個(gè)樣式化的表單!
使用* ngFor添加powers
英雄必須從一個(gè)固定的機(jī)構(gòu)批準(zhǔn)的權(quán)力列表中選擇一個(gè)超級(jí)大國。 您在內(nèi)部維護(hù)該列表(在HeroFormComponent中)。
您將在表單中添加一個(gè)select,并使用ngFor(先前在“顯示數(shù)據(jù)”頁面中看到的一種技術(shù))將選項(xiàng)綁定到powers列表。
在Alter Ego?group下方添加以下HTML:lib/src/hero_form_component.html (powers)
<div class="form-group"><label for="power">Hero Power *</label><select class="form-control" id="power" required><option *ngFor="let p of powers" [value]="p">{{p}}</option></select> </div>這段代碼重復(fù)列表中每個(gè)power?的<option>標(biāo)簽。 p模板輸入變量在每次迭代中是不同的power; 您使用插值語法顯示其名稱。
與ngModel的雙向數(shù)據(jù)綁定
現(xiàn)在運(yùn)行應(yīng)用程序有點(diǎn)令人失望。
你沒有看到英雄數(shù)據(jù),因?yàn)槟氵€沒有綁定到英雄。 你知道如何從早期的頁面做到這一點(diǎn)。 顯示數(shù)據(jù)教導(dǎo)屬性綁定。 用戶輸入顯示如何使用事件綁定監(jiān)聽DOM事件以及如何使用顯示的值更新組件屬性。
現(xiàn)在您需要同時(shí)顯示,聆聽和提取。
你可以使用你已經(jīng)知道的技術(shù),但是你會(huì)使用新的[(ngModel)]語法,這使得綁定到模型的表單變得容易。
找到Name的<input>標(biāo)簽,并像下面這樣更新它:lib/src/hero_form_component.html (name)
<!-- TODO: remove the next diagnostic line --> <mark>{{model.name}}</mark><hr> <div class="form-group"><label for="name">Name *</label><input type="text" class="form-control" id="name" required[(ngModel)]="model.name"ngControl="name"> </div>你在form-group之前添加了一個(gè)診斷插值,所以你可以看到你在做什么。 當(dāng)你完成的時(shí)候,你留下一張紙條扔掉它。
關(guān)注綁定語法:[(ngModel)] =“...”。
現(xiàn)在運(yùn)行應(yīng)用程序并輸入名稱輸入,添加和刪除字符。 您會(huì)看到這些字符出現(xiàn)在診斷文本中并消失。 在某個(gè)時(shí)候,它可能看起來像這樣:
診斷結(jié)果表明數(shù)值確實(shí)是從輸入流向模型,再返回。
這是雙向的數(shù)據(jù)綁定。 有關(guān)更多信息,請(qǐng)參見模板語法頁面上的與NgModel的雙向綁定。
請(qǐng)注意,您還為<input>標(biāo)記添加了一個(gè)ngControl指令,并將其設(shè)置為“name”,這對(duì)于英雄的名字是有意義的。 任何唯一值將會(huì)這樣做,但使用描述性名稱是有幫助的。 將[(ngModel)]與表單結(jié)合使用時(shí),定義ngControl指令是一項(xiàng)要求。
在內(nèi)部,Angular創(chuàng)建NgFormControl實(shí)例,并使用Angular附加到<form>標(biāo)簽的NgForm指令注冊(cè)它們。 每個(gè)NgFormControl都是在您分配給ngControl指令的名稱下注冊(cè)的。 本指南稍后將詳細(xì)介紹NgForm。
在Alter Ego和Hero Power上添加類似的[(ngModel)]綁定和ngControl指令。
用model替換診斷綁定表達(dá)式。 通過這種方式,您可以確認(rèn)雙向數(shù)據(jù)綁定適用于整個(gè)英雄模型。
修改后,表單的核心應(yīng)該是這樣的:lib/src/hero_form_component.html (controls)
<!-- TODO: remove the next diagnostic line --> <mark>{{model}}</mark><hr> <div class="form-group"><label for="name">Name *</label><input type="text" class="form-control" id="name" required[(ngModel)]="model.name"ngControl="name"> </div> <div class="form-group"><label for="alterEgo">Alter Ego</label><input type="text" class="form-control" id="alterEgo"[(ngModel)]="model.alterEgo"ngControl="alterEgo"> </div> <div class="form-group"><label for="power">Hero Power *</label><select class="form-control" id="power" required[(ngModel)]="model.power"ngControl="power"><option *ngFor="let p of powers" [value]="p">{{p}}</option></select> </div>- 每個(gè)input元素都有一個(gè)id屬性,label元素的for屬性使用它來匹配label和input控件。
- 每個(gè)input元素都有一個(gè)ngControl指令,Angular表單需要用這個(gè)指令在表單上注冊(cè)控件。
如果您現(xiàn)在運(yùn)行應(yīng)用程序并更改每個(gè)英雄model屬性,表單可能會(huì)顯示如下:
靠近表單頂部的診斷確認(rèn)所有的更改都反映在model中。
從模板中刪除診斷綁定,因?yàn)樗呀?jīng)達(dá)到了目的。
根據(jù)控制狀態(tài)給出視覺反饋
使用CSS和類綁定,您可以更改表單控件的外觀以反映其狀態(tài)。
跟蹤控制狀態(tài)
Angular表單控件可以告訴您用戶是否觸摸了該控件,值是否改變,或者該值是否失效。
每個(gè)Angular控制(NgControl)都跟蹤自己的狀態(tài),并通過以下字段成員使?fàn)顟B(tài)可供檢查:
- dirty和pristine表明控制的值是否已經(jīng)改變。
- touched和untouched指示控件是否被訪問過。
- valid反映了控制值的有效性。
樣式控件
有效的控制屬性是最有趣的,因?yàn)楫?dāng)一個(gè)控制值無效時(shí),你想發(fā)送一個(gè)強(qiáng)烈的視覺信號(hào)。 要?jiǎng)?chuàng)建這樣的視覺反饋,您將使用Bootstrap自定義表單類?is-valid和is-invalid。
將名為name的模板引用變量添加到Name <input>標(biāo)記中。 使用name和類綁定來有條件地分配適當(dāng)?shù)谋韱斡行灶悺?/p>
臨時(shí)將另一個(gè)名為spy的模板引用變量添加到Name <input>標(biāo)記,并使用它顯示輸入的CSS類。
lib/src/hero_form_component.html (name)
<input type="text" class="form-control" id="name" required[(ngModel)]="model.name"#name="ngForm"#spy[class.is-valid]="name.valid"[class.is-invalid]="!name.valid"ngControl="name"> <!-- TODO: remove the next diagnostic line --> {{spy.className}}模板引用變量
spy模板引用變量綁定到<input> DOM元素,而name變量(通過#name =“ngForm”語法)綁定到與input元素關(guān)聯(lián)的NgModel。
為什么“ngForm”? 指令的exportAs屬性告訴Angular如何將引用變量鏈接到指令。 您將name設(shè)置為“ngForm”,因?yàn)?span style="color:#008000;">ngModel指令的exportAs屬性是“ngForm”。
刷新瀏覽器,然后按照下列步驟操作:
1.看看名字輸入。
- 它有一個(gè)綠色的邊框。
- 它具有類形式控制和有效性。
2.通過添加一些字符來更改name。 類保持不變。
3.刪除名稱。
- 輸入框邊框變?yōu)榧t色。
- is-invalid類替換為is-valid。
刪除#spy模板引用變量和使用它的診斷。
作為類綁定的替代方法,可以使用NgClass指令來設(shè)置控件的樣式。 首先,添加以下方法來設(shè)置控件的依賴于狀態(tài)的CSS類名稱:
lib/src/hero_form_component.dart (setCssValidityClass)
Map<String, bool> setCssValidityClass(NgControl control) {final validityClass = control.valid == true ? 'is-valid' : 'is-invalid';return {validityClass: true}; }使用此方法返回的映射值綁定到NgClass指令 - 在模板語法頁面中詳細(xì)了解此指令及其替代方法。
lib/src/hero_form_component.html (power)
<select class="form-control" id="power" required[(ngModel)]="model.power"#power="ngForm"[ngClass]="setCssValidityClass(power)"ngControl="power"><option *ngFor="let p of powers" [value]="p">{{p}}</option> </select>顯示并隱藏驗(yàn)證錯(cuò)誤消息
你可以改善表格。 名稱輸入是必需的,清除它將框的輪廓變?yōu)榧t色。 這說明有些事情是錯(cuò)的,但用戶不知道什么是錯(cuò)的,或者該怎么做。 利用控件的狀態(tài)來顯示有用的消息。
使用有效的和原始的狀態(tài)
當(dāng)用戶刪除名稱時(shí),表單應(yīng)該如下所示:
為了達(dá)到這個(gè)效果,在Name <input>之后立即添加下面的<div>:
lib/src/hero_form_component.html (hidden error message)
<div [hidden]="name.valid || name.pristine" class="invalid-feedback">Name is required </div>刷新瀏覽器并刪除Name?輸入。 顯示錯(cuò)誤消息。
您可以通過根據(jù)名稱控制的狀態(tài)設(shè)置<div>的隱藏屬性來控制錯(cuò)誤消息的可見性。
在這個(gè)例子中,當(dāng)控件是有效的或者原始的時(shí)候隱藏消息 - “pristine”意味著用戶沒有改變這個(gè)值,因?yàn)樗且赃@種形式顯示的。
用戶體驗(yàn)是開發(fā)者的選擇
有些開發(fā)人員希望消息始終顯示。 如果您忽略原始狀態(tài),則只有在該值有效時(shí)才會(huì)隱藏該消息。 如果您使用新(空白)英雄或無效英雄到達(dá)此組件,則在您執(zhí)行任何操作之前,您將立即看到錯(cuò)誤消息。
有些開發(fā)人員希望僅在用戶進(jìn)行無效更改時(shí)顯示消息。 當(dāng)控件是“原始的”時(shí)隱藏消息實(shí)現(xiàn)了這個(gè)目標(biāo)。 當(dāng)您向表單添加一個(gè)“清除”按鈕時(shí),您會(huì)看到此選項(xiàng)的重要性。
英雄Alter Ego是可選的,所以你可以不用關(guān)那個(gè)。
英雄power選擇是必需的。 如果需要,可以將相同類型的錯(cuò)誤消息添加到<select>中,但這不是必須的,因?yàn)檫x擇框已經(jīng)將權(quán)限限制為有效值。
添加一個(gè)清除按鈕
將clear()方法添加到組件類中:lib/src/hero_form_component.dart (clear)
void clear() {model.name = '';model.power = _powers[0];model.alterEgo = ''; }在提交按鈕后面添加一個(gè)帶有點(diǎn)擊事件綁定的清除按鈕:lib/src/hero_form_component.html (Clear button)
<button (click)="clear()" type="button" class="btn">Clear </button>刷新瀏覽器。 點(diǎn)擊清除按鈕。 文本字段變?yōu)榭瞻?#xff0c;如果您更改了power,它將恢復(fù)為默認(rèn)值。
用ngSubmit提交表單
用戶應(yīng)該能夠在填寫表單后提交這個(gè)表單。表單底部的Submit按鈕本身不做任何事情,但是由于它的類型(type =“submit”),它會(huì)觸發(fā)一個(gè)表單提交。
表單提交目前是無用的。 為了使它有用,將表單組件的onSubmit()方法分配給表單的ngSubmit事件綁定:
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">請(qǐng)注意模板引用變量#heroForm。 正如前面所解釋的,變量heroForm被綁定到整體管理表單的NgForm指令。
NgForm指令
Angular自動(dòng)創(chuàng)建并附加一個(gè)NgForm指令給<form>標(biāo)簽。
NgForm指令補(bǔ)充表單元素的附加功能。 它包含用ngModel和ngControl指令為元素創(chuàng)建的控件,并監(jiān)視它們的屬性,包括它們的有效性。
您將通過heroForm變量將表單的整體有效性綁定到按鈕的disabled屬性:
<button [disabled]="!heroForm.form.valid" type="submit" class="btn btn-primary">Submit </button>刷新瀏覽器。 你會(huì)發(fā)現(xiàn)這個(gè)按鈕是啟用的,盡管它沒有做任何有用的事情。
現(xiàn)在,如果您刪除Name,則違反了“必需的”規(guī)則,這在錯(cuò)誤消息中正確記錄。 提交按鈕也被禁用。
沒有留下深刻印象? 想一想。 如果沒有Angular的幫助,你需要做什么才能將按鈕的啟用/禁用狀態(tài)連接到表單的有效性?
對(duì)你來說,這很簡單:
- 在(增強(qiáng)的)表單元素上定義一個(gè)模板引用變量。
- 在多處的按鈕中引用該變量。
顯示Model(可選)
提交表單目前沒有視覺效果。
如預(yù)期的演示。 增加代碼過后的demo不會(huì)教你任何關(guān)于表單的新東西。 但是這是一個(gè)鍛煉一些新獲得的綁定技巧的機(jī)會(huì)。 如果您不感興趣,請(qǐng)?zhí)帘卷摰恼?/p>
作為一種視覺效果,您可以隱藏?cái)?shù)據(jù)輸入?yún)^(qū)域并顯示其他內(nèi)容。
將表單封裝在<div>中,并將其hidden屬性綁定到HeroFormComponent.submitted屬性。
lib/src/hero_form_component.html (excerpt)
<div [hidden]="submitted"><h1>Hero Form</h1><form (ngSubmit)="onSubmit()" #heroForm="ngForm"></form> </div>該表單從一開始就是可見的,因?yàn)樵谔峤槐韱沃?#xff0c;提交的屬性為false,因?yàn)?span style="color:#008000;">HeroFormComponent中的片段顯示為:lib/src/hero_form_component.dart (submitted)
bool submitted = false;void onSubmit() => submitted = true;現(xiàn)在在剛剛寫的<div>包裝器下面添加下面的HTML:lib/src/hero_form_component.html (submitted)
<div [hidden]="!submitted"><h1>Hero data</h1><table class="table"><tr><th>Name</th><td>{{model.name}}</td></tr><tr><th>Alter Ego</th><td>{{model.alterEgo}}</td></tr><tr><th>Power</th><td>{{model.power}}</td></tr></table><button (click)="submitted=false" class="btn btn-primary">Edit</button> </div>刷新瀏覽器并提交表單。 提交的標(biāo)志變?yōu)檎?#xff0c;表格消失。 您將看到表格中顯示的英雄模型值(只讀)。
該視圖包含一個(gè)編輯按鈕,其單擊事件綁定將清除提交的標(biāo)志。 當(dāng)您單擊編輯按鈕時(shí),該表消失,并且可編輯的表單重新出現(xiàn)。
概要
Angular表單為數(shù)據(jù)修改,驗(yàn)證等提供支持。 在此頁面中,您學(xué)習(xí)了如何使用以下功能:
- 一個(gè)HTML表單模板和一個(gè)帶有@Component注解的表單組件類。
- 表單提交,通過ngSubmit事件綁定處理。
- 模板引用變量,如heroForm和name。
- 雙向數(shù)據(jù)綁定([(ngModel)])。
- 用于驗(yàn)證和表單元素更改跟蹤的NgControl?指令。
- 輸入控件(通過模板引用變量訪問)的valid?屬性,用于檢查控件有效性以及顯示/隱藏錯(cuò)誤消息。
- NgForm.form的有效性來設(shè)置提交按鈕的啟用狀態(tài)。
- 自定義CSS類為用戶提供有關(guān)控制狀態(tài)的可視反饋。
最終的項(xiàng)目文件夾結(jié)構(gòu)應(yīng)該如下所示:
以下是應(yīng)用程序最終版本的代碼:
lib/app_component.dart
import 'package:angular/angular.dart'; import 'src/hero_form_component.dart'; @Component(selector: 'my-app',template: '<hero-form></hero-form>',directives: const [HeroFormComponent], ) class AppComponent {}lib/src/hero.dart?
class Hero {int id;String name, power, alterEgo;Hero(this.id, this.name, this.power, [this.alterEgo]);String toString() => '$id: $name ($alterEgo). Super power: $power'; }lib/src/hero_form_component.dart
import 'package:angular/angular.dart'; import 'package:angular_forms/angular_forms.dart'; import 'hero.dart'; const List<String> _powers = const ['Really Smart','Super Flexible','Super Hot','Weather Changer' ]; @Component(selector: 'hero-form',templateUrl: 'hero_form_component.html',directives: const [CORE_DIRECTIVES, formDirectives], ) class HeroFormComponent {Hero model = new Hero(18, 'Dr IQ', _powers[0], 'Chuck Overstreet');bool submitted = false;List<String> get powers => _powers;void onSubmit() => submitted = true;/// Returns a map of CSS class names representing the state of [control].Map<String, bool> setCssValidityClass(NgControl control) {final validityClass = control.valid == true ? 'is-valid' : 'is-invalid';return {validityClass: true};}void clear() {model.name = '';model.power = _powers[0];model.alterEgo = '';} }lib/src/hero_form_component.html
<div class="container"><div [hidden]="submitted"><h1>Hero Form</h1><form (ngSubmit)="onSubmit()" #heroForm="ngForm"><div class="form-group"><label for="name">Name *</label><input type="text" class="form-control" id="name" required[(ngModel)]="model.name"#name="ngForm"[class.is-valid]="name.valid"[class.is-invalid]="!name.valid"ngControl="name"><div [hidden]="name.valid || name.pristine" class="invalid-feedback">Name is required</div></div><div class="form-group"><label for="alterEgo">Alter Ego</label><input type="text" class="form-control" id="alterEgo"[(ngModel)]="model.alterEgo"ngControl="alterEgo"></div><div class="form-group"><label for="power">Hero Power *</label><select class="form-control" id="power" required[(ngModel)]="model.power"#power="ngForm"[ngClass]="setCssValidityClass(power)"ngControl="power"><option *ngFor="let p of powers" [value]="p">{{p}}</option></select></div><div class="row"><div class="col-auto"><button [disabled]="!heroForm.form.valid" type="submit" class="btn btn-primary">Submit</button><button (click)="clear()" type="button" class="btn">Clear</button></div><small class="col text-right">* Required</small></div></form></div><div [hidden]="!submitted"><h1>Hero data</h1><table class="table"><tr><th>Name</th><td>{{model.name}}</td></tr><tr><th>Alter Ego</th><td>{{model.alterEgo}}</td></tr><tr><th>Power</th><td>{{model.power}}</td></tr></table><button (click)="submitted=false" class="btn btn-primary">Edit</button></div> </div>web/index.html
<!DOCTYPE html> <html><head><script>// WARNING: DO NOT set the <base href> like this in production!// Details: https://webdev.dartlang.org/angular/guide/router(function () {var m = document.location.pathname.match(/^(\/[-\w]+)+\/web($|\/)/);document.write('<base href="' + (m ? m[0] : '/') + '" />');}());</script><title>Hero Form</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"crossorigin="anonymous"><link rel="stylesheet" href="styles.css"><link rel="icon" type="image/png" href="favicon.png"><script defer src="main.dart" type="application/dart"></script><script defer src="packages/browser/dart.js"></script></head><body><my-app>Loading ...</my-app></body> </html>web/main.dart
import 'package:angular/angular.dart'; import 'package:forms/app_component.dart'; void main() {bootstrap(AppComponent); }?
轉(zhuǎn)載于:https://my.oschina.net/u/3647851/blog/1585929
總結(jié)
以上是生活随笔為你收集整理的AngularDart4.0 指南- 表单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经常梦到眼睛看不见是怎么回事
- 下一篇: 孕妇梦到涨大水预示着什么