概述
select指令实现的是下拉框的功能,一般会配合option指令以及ng-model指令使用。在select指令中常用的一些指令:
指令 | 说明 |
---|---|
ng-model | 绑定的数据 |
required,ng-required | 指定是否为必须的,具体可以查看required指令相关内容 |
multiple | 是否可以多选 |
ng-change | 选择发生变化时的响应 |
ng-option | select的可选项 |
在option指令中,会把value属性或者textContent的值作为选中的值,优先使用value的值,optiong只会有string类型的值,如果不是string类型的值就无法正确处理。如果想要option绑定一个不是字符串格式的值就需要特殊处理一下。
当select绑定的数据无法在已有的option中找到时,就会自动添加一个对应的option,这个option显示的是空的,当数据变化后就会删除。
实现细节
在select指令中主要实现了上个部分:controller,prelink,postlink。
controller中主要实现了一些功能函数:
函数 | 说明 |
---|---|
renderUnknownOption | 创建一个未知option |
updateUnknownOption | 更新未知option |
generateUnknownOptionValue | 获取未知option的值 |
removeUnknownOption | 删除未知option |
selectEmptyOption | 选择空option |
unselectEmptyOption | 去除空option的选择状态 |
readValue | 读取选中的值,multiple会从写这个函数 |
writeValue | 根据数据改变option选择状态,multiple会从写这个函数 |
addOption | 添加option |
removeOption | 删除option |
hasOption | 判断option是否存在 |
registerOption | 注册option |
prelink中主要change事件的监听以及如果是multiple类型时从写readValue和writeValue方法。
postlink里主要做的事情是复写ng-model的controller的$render方法,这个方法在页面刷新时会被调用。
在option指令中,最主要的工作是把自己的信息注册到select中去,调用select controller的registerOption方法。
var selectCtrlName = '$selectController',
parent = element.parent(),
selectCtrl = parent.data(selectCtrlName) ||
parent.parent().data(selectCtrlName); // in case we are in optgroup
if (selectCtrl) {
selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);
}
从代码可以看出option指令中会尝试获取父标签或父标签的父标签的controller,这个controller对应的就是select中的controller,所以option指令必须配合select指令或者实现了registerOption方法的指令使用。
样例代码
<!DOCTYPE html>
<html lang="en" ng-app="app">
<!--<html>-->
<head>
<title>Test</title>
</head>
<body>
<div ng-controller="ExampleController">
<form name="myForm">
<label for="singleSelect"> Single select: </label><br>
<select name="singleSelect" ng-model="data.singleSelect">
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
</select><br>
<label for="singleSelect"> Single select with "not selected" option and dynamic option values: </label><br>
<select name="singleSelect" id="singleSelect" ng-model="data.singleSelect">
<option value="">---Please select---</option> <!-- not selected / blank option -->
<option value="{{data.option1}}">Option 1</option> <!-- interpolation -->
<option value="option-2">Option 2</option>
</select><br>
<button ng-click="forceUnknownOption()">Force unknown option</button><br>
<tt>singleSelect = {{data.singleSelect}}</tt>
<hr>
<label for="multipleSelect"> Multiple select: </label><br>
<select name="multipleSelect" id="multipleSelect" ng-model="data.multipleSelect" multiple>
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
<option value="option-3">Option 3</option>
</select><br>
<tt>multipleSelect = {{data.multipleSelect}}</tt><br/>
</form>
</div>
<script src="./node_modules/angular/angular.js" type="text/javascript"></script>
<script>
angular.module('app', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.data = {
singleSelect: null,
multipleSelect: [],
option1: 'option-1'
};
$scope.forceUnknownOption = function() {
$scope.data.singleSelect = 'nonsense';
};
}]);
</script>
</body>
</html>