数值与单位对应转换

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/

原文地址:https://www.cnblogs.com/echo2016/p/5681621.html