概述
ng-model-options指令用来更改ng-model等指令的默认行为,这个指令可以在任何位置使用,它会影响ng-model和输入型指令以及他们的派生指令。ng-model-options指令可以被指定为一个运算式,但是这个运算式在通过Angular计算后必须得到一个Object,这个Object的属性就是设置项。
一个指令的option值是会向上计算的,比如:
<div ng-model-options="{ allowInvalid: true }">
<form ng-model-options="{ updateOn: 'blur' }">
<input ng-model-options="{ updateOn: 'default' }" />
</form>
</div>
在这段代码中,input元素的options属性为:
{ allowInvalid: true, updateOn: 'default' }
实现细节
ng-model-options指令的基础是$modelOptionsProvider。
provider的核心代码:
var _options = extend({}, parentOptions, options);
在这个provider中,最核心的代码只有一行,这行代码实现了上面所说的option向上合并的功能。
在ng-model-options指令中,最关键的部分在link中:
pre: function ngModelOptionsPreLinkFn(scope, element, attrs, ctrls) {
var optionsCtrl = ctrls[0];
var parentOptions = ctrls[1] ? ctrls[1].$options : $modelOptions;
optionsCtrl.$options = parentOptions.createChild(scope.$eval(attrs.ngModelOptions));
}
在这里会根据父option以及自己的ng-model-options属性创建一个options,利用的是$modelOptionsProvider提供的功能。
options默认值:
属性 | 默认值 |
---|---|
updateOn | default |
debounce | 0 |
allowInvalid | undefined |
getterSetter | undefined |
timezone | undefined |
样例代码
<!DOCTYPE html>
<html lang="en" ng-app="app">
<!--<html>-->
<head>
<title>Test</title>
</head>
<body>
<div ng-controller="ExampleController">
<form name="userForm">
<label>
Name:
<input type="text" name="userName"
ng-model="user.name"
ng-model-options="{ updateOn: 'blur' }"
ng-keyup="cancel($event)" />
</label><br />
<label>
Other data:
<input type="text" ng-model="user.data" />
</label><br />
</form>
<pre>user.name = <span ng-bind="user.name"></span></pre>
</div>
<script src="./node_modules/angular/angular.js" type="text/javascript"></script>
<script>
angular.module('app', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.user = { name: 'say', data: '' };
$scope.cancel = function(e) {
if (e.keyCode === 27) {
$scope.userForm.userName.$rollbackViewValue();
}
};
}]);
</script>
</body>
</html>
这段代码修改了默认数据更新方式,在输入焦点发生变化的时候才会把数据写入到scope中去。