### 7.5. 表單控件
表單控件類的模板指令,最大的作用是它預定義了需要綁定的數據的格式。這樣,就可以對于既定的數據進行既定的處理。
### 7.5.1. form
_form_ 是核心的一個控件。 ng 對 _form_ 這個標簽作了包裝。事實上, ng 自己的指令是叫 _ng-form_ 的,區別在于, _form_ 標簽不能嵌套,而使用 _ng-form_ 指令就可以做嵌套的表單了。
_form_ 的行為中依賴它里面的各個輸入控制的狀態的,在這里,我們主要關心的是 _form_ 自己的一些方法和屬性。從 ng 的角度來說, _form_ 標簽,是一個模板指令,也創建了一個 _FormController_ 的實例。這個實例就提供了相應的屬性和方法。同時,它里面的控件也是一個 _NgModelController_ 實例。
很重要的一點, _form_ 的相關方法要生效,必須為 _form_ 標簽指定 _name_ 和 _ng-controller_ ,并且每個控件都要綁定一個變量。 _form_ 和控件的名字,即是 _$scope_ 中的相關實例的引用變量名。
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" required ng-model="a" />
<span ng-click="see()">{{ test_form.$valid }}</span>
</form>
var TestCtrl = function($scope){
$scope.see = function(){
console.log($scope.test_form);
console.log($scope.test_form.a);
}
}
除去對象的方法與屬性, _form_ 這個標簽本身有一些動態類可以使用:
- _ng-valid_ 當表單驗證通過時的設置
- _ng-invalid_ 當表單驗證失敗時的設置
- _ng-pristine_ 表單的未被動之前擁有
- _ng-dirty_ 表單被動過之后擁有
_form_ 對象的屬性有:
- _$pristine_ 表單是否未被動過
- _$dirty_ 表單是否被動過
- _$valid_ 表單是否驗證通過
- _$invalid_ 表單是否驗證失敗
- _$error_ 表單的驗證錯誤
其中的 _$error_ 對象包含有所有字段的驗證信息,及對相關字段的 _NgModelController_ 實例的引用。它的結構是一個對象, `key` 是失敗信息, _required_ , _minlength_ 之類的, `value` 是對應的字段實例列表。
注意,這里的失敗信息是按序列取的一個。比如,如果一個字段既要求 _required_ ,也要求 _minlength_ ,那么當它為空時, _$error_ 中只有 _required_ 的失敗信息。只輸入一個字符之后, _required_ 條件滿足了,才可能有 _minlength_ 這個失敗信息。
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" required ng-model="a" />
<input type="text" name="b" required ng-model="b" ng-minlength="2" />
<span ng-click="see()">{{ test_form.$error }}</span>
</form>
var TestCtrl = function($scope){
$scope.see = function(){
console.log($scope.test_form.$error);
}
}
### 7.5.2. input
_input_ 是數據的最主要入口。 ng 支持 HTML5 中的相關屬性,同時對舊瀏覽器也做了兼容性處理。最重要的, _input_ 的規則定義,是所屬表單的相關行為的參照(比如表單是否驗證成功)。
_input_ 控件的相關可用屬性為:
- _name_ 名字
- _ng-model_ 綁定的數據
- _required_ 是否必填
- _ng-required_ 是否必填
- _ng-minlength_ 最小長度
- _ng-maxlength_ 最大長度
- _ng-pattern_ 匹配模式
- _ng-change_ 值變化時的回調
<form name="test_form" ng-controller="TestCtrl">
<input type="text" name="a" ng-model="a" required ng-pattern="/abc/" />
<span ng-click="see()">{{ test_form.$error }}</span>
</form>
_input_ 控件,它還有一些擴展,這些擴展有些有自己的屬性:
- _input type="number"_ 多了 `number` 錯誤類型,多了 _max_ , _min_ 屬性。
- _input type="url"_ 多了 `url` 錯誤類型。
- _input type="email"_ 多了 `email` 錯誤類型。
### 7.5.3. checkbox
它也算是 _input_ 的擴展,不過,它沒有驗證相關的東西,只有選中與不選中兩個值:
<form name="test_form" ng-controller="TestCtrl">
<input type="checkbox" name="a" ng-model="a" ng-true-value="AA" ng-false-value="BB" />
<span>{{ a }}</span>
</form>
var TestCtrl = function($scope){
$scope.a = 'AA';
}
兩點:
1. controller 要初始化變量值。
1. controller 中的初始化值會關系到控件狀態(雙向綁定)。
### 7.5.4. radio
也是 _input_ 的擴展。和 _checkbox_ 一樣,但它只有一個值了:
<form name="test_form" ng-controller="TestCtrl">
<input type="radio" name="a" ng-model="a" value="AA" />
<input type="radio" name="a" ng-model="a" value="BB" />
<span>{{ a }}</span>
</form>
### 7.5.5. textarea
同 _input_ 。
### 7.5.6. select
這是一個比較牛B的控件。它里面的一個叫做 _ng-options_ 的屬性用于數據呈現。
對于給定列表時的使用。
最簡單的使用方法, `x for x in list` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o=[0,1,2,3]; a=o[1];">
<select ng-model="a" ng-options="x for x in o" ng-change="show()">
<option value="">可以加這個空值</option>
</select>
</form>
<script type="text/javascript">
var TestCtrl = function($scope){
$scope.show = function(){
console.log($scope.a);
}
}
angular.bootstrap(document.documentElement);
</script>
在 _$scope_ 中, _select_ 綁定的變量,其值和普通的 _value_ 無關,可以是一個對象:
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA'}, {name: 'BB'}]; a=o[1];">
<select ng-model="a" ng-options="x.name for x in o" ng-change="show()">
</select>
</form>
顯示與值分別指定, `x.v as x.name for x in o` :
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA', v: '00'}, {name: 'BB', v: '11'}]; a=o[1].v;">
<select ng-model="a" ng-options="x.v as x.name for x in o" ng-change="show()">
</select>
</form>
加入分組的, `x.name group by x.g for x in o` :
<form name="test_form" ng-controller="TestCtrl"
ng-init="o=[{name: 'AA', g: '00'}, {name: 'BB', g: '11'}, {name: 'CC', g: '00'}]; a=o[1];">
<select ng-model="a" ng-options="x.name group by x.g for x in o" ng-change="show()">
</select>
</form>
分組了還分別指定顯示與值的, `x.v as x.name group by x.g for x in o` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o=[{name: 'AA', g: '00', v: '='}, {name: 'BB', g: '11', v: '+'}, {name: 'CC', g: '00', v: '!'}]; a=o[1].v;">
<select ng-model="a" ng-options="x.v as x.name group by x.g for x in o" ng-change="show()">
</select>
</form>
如果參數是對象的話,基本也是一樣的,只是把遍歷的對象改成 `(key, value)` :
<form name="test_form" ng-controller="TestCtrl" ng-init="o={a: 0, b: 1}; a=o.a;">
<select ng-model="a" ng-options="k for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00'}, b: {name: 'BB', v: '11'}}; a=o.a.v;">
<select ng-model="a" ng-options="v.v as v.name for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00', g: '=='}, b: {name: 'BB', v: '11', g: '=='}}; a=o.a;">
<select ng-model="a" ng-options="v.name group by v.g for (k, v) in o" ng-change="show()">
</select>
</form>
<form name="test_form" ng-controller="TestCtrl"
ng-init="o={a: {name: 'AA', v: '00', g: '=='}, b: {name: 'BB', v: '11', g: '=='}}; a=o.a.v;">
<select ng-model="a" ng-options="v.v as v.name group by v.g for (k, v) in o" ng-change="show()">
</select>
</form>
- Introduction
- 關于AngularJS
- 關于本文檔
- 開始的例子
- 依賴注入
- 作用域
- 數據綁定與模板
- 數據->模板
- 模板->數據
- 數據->模板->數據->模板
- 模板
- 定義模板內容
- 內容渲染控制
- 節點控制
- 事件綁定
- 表單控件
- 模板中的過濾器
- 排序 orderBy
- 過濾列表 filter
- 其它
- 例子:表頭排序
- 例子:搜索
- 錨點路由
- 路由定義
- 參數定義
- 業務處理
- 定義模板變量標識標簽
- AJAX
- HTTP請求
- 廣義回調管理
- 工具函數
- 上下文綁定
- 對象處理
- 類型判定
- 其它服務
- 日志
- 緩存
- 計時器
- 表達式函數化
- 模板單獨使用
- 自定義模塊和服務
- 模塊和服務的概念與關系
- 定義模塊
- 定義服務
- 引入模塊并使用服務
- 附加模塊 ngResource
- 使用引入與整體概念
- 基本定義
- 基本使用
- 定義和使用時的占位量
- 實例
- AngularJS與其它框架的混用(jQuery, Dojo)
- 自定義過濾器
- 自定義指令directive
- 指令的使用
- 指令的執行過程
- 基本的自定義方法
- 屬性值類型的自定義
- Compile的細節
- transclude的細節
- 把節點內容作為變量處理的類型
- 指令定義時的參數
- Attributes的細節
- 預定義的 NgModelController
- 預定義的 FormController
- 示例:文本框
- 示例:模板控制語句 for
- 示例:模板控制語句 if/else