function TimeDurationDirective() {
var tpl = "<div>
<input type='text' ng-model='num' size='80' />
<select ng-model='unit'>
<option value='secs'>Seconds</option>
<option value='mins'>Minutes</option>
<option value='hours'>Hours</option>
<option value='days'>Days</option>
</select>
</div>";
return {
restrict: 'E',
template: tpl,
require: 'ngModel',
replace: true,
link: function(scope, iElement, iAttrs, ngModelCtrl) {
//TODO
}
};
};
angular.module('myModule').directive('timeDuration', TimeDurationDirective);
//$formatters部分
link: function(scope, iElement, iAttrs, ngModelCtrl) { // Units of time multiplierMap = {seconds: 1, minutes: 60, hours: 3600, days: 86400}; multiplierTypes = ['seconds', 'minutes', 'hours', 'days'] ngModelCtrl.$formatters.push(function(modelValue) { var unit = 'minutes', num = 0, i, unitName; modelValue = parseInt(modelValue || 0); // Figure out the largest unit of time the model value // fits into. For example, 3600 is 1 hour, but 1800 is 30 minutes. for (i = multiplierTypes.length-1; i >= 0; i--) { unitName = multiplierTypes[i]; if (modelValue % multiplierMap[unitName] === 0) { unit = unitName; break; } } if (modelValue) { num = modelValue / multiplierMap[unit] } return { unit: unit, num: num }; }); }
//各个值的情况 $scope.email_notify_pref = 3600 ngModelCtrl.$formatters(3600) $viewValue = { unit: 'hours', num: 1}
ngModelCtrl.$render用来渲染$viewValue值到UI界面中
ngModelCtrl.$render = function() { scope.unit = ngModelCtrl.$viewValue.unit; scope.num = ngModelCtrl.$viewValue.num; };
//the$parsers
pipeline that converts the$viewValue
into the$modelValue
ngModelCtrl.$parsers.push(function(viewValue) { var unit = viewValue.unit, num = viewValue.num, multiplier; // Remember multiplierMap was defined above // in the formatters snippet multiplier = multiplierMap[unit]; return num * multiplier; });
// $pasers得到的值情况
$viewValue.email_notify_pref = { unit: 'hours', num: 1 }; ngModelCtrl.$parsers({unit: 'hours', num: 1}) $modelValue = 3600;
Updating $viewValue when the UI changes:
scope.$watch('unit + num', function() { ngModelCtrl.$setViewValue({ unit: scope.unit, num: scope.num }); });
整个流程如图:
<realModel> → ngModelCtrl.$formatters(realModel) → $viewModel
↓
↑ $render()
↓
↑ UI changed
↓
ngModelCtrl.$parsers(newViewModel) ← $setViewModel(newViewModel)
<h3>My Super App</h3> How often should we email you? <time-duration ng-mode="email_notify_pref" />
原文地址:https://www.nadeau.tv/using-ngmodelcontroller-with-custom-directives/