指令是angular框架提供的一个强大的功能,angular本身就是一个MVVM框架;
在自定义指令中,model与view之间的交互以及变化是很频繁的,angular提供了两个管道数组,$Formatters & $Parsers,让我们在自定义指令是用来控制view&model之间的变化;
以下是官方文档定义:
$formatters:
Array of functions to execute,as a pipeline,whenever the bound ngModel expression changes programmatically. The $formatters are not called when the value of the control is changed by user interaction.Formatters are used to format / convert the $modelValue for display in the control.The functions are called in reverse array order,each passing the value through to the next. The last return value is used as the actual DOM value.$parsers :
Array of functions to execute,whenever the control updates the ngModelController with a new $viewValue from the DOM,usually via user input. See $setViewValue() for a detailed lifecycle explanation. Note that the $parsers are not called when the bound ngModel expression changes programmatically.The functions are called in array order,each passing its return value through to the next. The last return value is forwarded to the $validators collection.
Parsers are used to sanitize / convert the $viewValue.
首先要知道,view 与model之间总是存在联系的,两者之间总是会因为某些原因发生变化,用输入,按键会导致view变化,业务逻辑会导致model变化等;
formatters 和 parsers都是ngModelController中的属性 ,都是一个可执行函数数组,作为一个管道来使用;所有函数都是以管道形式执行,什么意思呢?就说每个函数之间都是有联系,他们是同步的,非异步,每个函数都是顺序执行的,这个顺序取决于使用者在添加可执行函数到formatter和parsers中的顺序,嗯就是这样;
除此,所有添加的进去的函数,如果需要参数,那么这个参数就是$viewValue(第一个执行的函数)或者上一个函数的返回值,所以说如果下一个函数需要参数,当前当前函数就必须返回值;
function format(value) {
if (value) {
return value.toUpperCase();
}
}
ngModel.$formatters.push(format);
\\**************************************
function parse(value) {
if (value) {
return value.toLowerCase();
}
}
ngModelController.$parsers.push(parse);
这些添加进去的可执行函数都不是我们手动执行,那么他们都会在什么时候以怎样的方式执行呢?
对于formatters属性,会有实时监听事件,当我们ng-model的数据以编程的方式改变时候,就会触发事件,此时会以管道形式执行所有函数,包括传参及其返回值操作;比如我们在通过js改变了值,此时就会触发事件;
对于parsers属性,也有事件监听,当ng-model数据在dom端发生变化时候,就会触发事件,执行管道函数;比较常见的就是用户输入/编辑值,写了图做为辅助理解(灵魂画风);
在实际应用方面,这两个属性的很好应用,可以减少我们自己对数据行为的监听;
其实细心就会发现两个属性所涉及范围是对立的,所以,不管是model还是view的变化,都会有很大的帮助;
parsers主要针对ngModelController.$viewValue,及其$setViewvalue();$viewValue是指令使用时所对应视图的实际值,$modelValue对应指令控制器所绑定的值,$viewValue与$modelValue的联系是$viewValue要通过$setViewValue方法,$modelValue的变化不一定会引起$viewValue的变化;当$viewValue发生变化时候,出发parsers中的函数执行;
//html
<div ng-app="myApp" ng-controller="myCtrl">
<input ng-model="data" type="text" ng-click="ddd()" test />
<span ng-click="changeModel()">{{data}}</span>
</div>
//js
angular.module('myApp',[])
.controller('myCtrl',function($scope){
$scope.data = 'yellow';
$scope.changeModel = function() {
$scope.data = 'yellow';
}
})
.directive('test',function(){
return {
require: 'ngModel',link: function(scope,elem,attrs,ngModel){
ngModel.$formatters.push(function(value){
//formats the value for display when ng-model is changed
return 'brown';
});
ngModel.$parsers.push(function(value){
//formats the value for ng-model when input value is changed
return 'green';
});
},controller: function($scope,$transclude,$compile,$element) {
}
};
});
可以点击链接运行实时观察变化;
更多请参官方文档