title: AngularJS how to force an input to be re-rendered on blur
body: <p>I have some custom validation code, which includes a $formatter.  (I store currency in pence for correctness, but display in pounds.pence.)</p>
  
  <p>If the user types '10' into the input (which is a valid value), the input remains displaying '10' after they move to the next field.</p>
  
  <p>I would like it to display 10.00 for consistency.</p>
  
  <p>If the model changed the value to 1000, then the formatter would make the field display '10.00'.</p>
  
  <p>I would like the formatter to run on field.blur() (so long as the input is valid).</p>
  
  <p>My problem is that if I change the model value from 10 to 10, there is understandably no change, and so the field is not re-rendered.</p>
  
  <p>code:</p>
  
  <pre><code>var CURRENCY_REGEXP = /^\-?\d+(\.?\d?\d?)?$/;
  app.directive('currency', function() {
    return {
      require: 'ngModel',
      link: function(scope, elm, attrs, ctrl) {
        ctrl.$parsers.unshift(function(viewValue) {
          if (CURRENCY_REGEXP.test(viewValue)) {
            // it is valid
            ctrl.$setValidity('currency', true);
            console.log("valid");
            return viewValue * 100;
          } else if (viewValue === '') {
            return 0;
          } else {
            // it is invalid, return undefined (no model update)
            ctrl.$setValidity('currency', false);
            console.log("invalid");
            return undefined;
          }
        });
        ctrl.$formatters.push(function(modelValue) {
           if (modelValue === 0) { // we're using integer pence, so this is safe
               return '';
           }
           return (modelValue / 100).toFixed(2); 
        });
      }
    };
  });
  </code></pre>
  
  <p>P.S. This has nothing to do with Angular's built-in 'currency'.</p>
  
  <hr>
  
  <p>Update: I've added a 'renderOnBlur' directive, as per Andy's answer.  It gets called, but calling the render method does not re-render the input.  i.e. '10' stays as '10', rather than changing to '10.00' as desired.  </p>
  
  <p>(When the model value changes in these fields, they are correctly rendered with the 2 decimal places.)</p>
  
  <p>The page which Andy mentions <a href="http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController" rel="noreferrer">http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController</a> says that you have to implement <code>$render</code> yourself.  This seems odd, as the inputs are already rendered correctly when the model value changes.</p>
  
  <pre><code>app.directive('renderOnBlur', function() {
      return {
          require: 'ngModel',
          restrict: 'A',
          link: function(scope, elm, attrs, ctrl) {
              elm.bind('blur', function() {
                  console.log('rendering ctrl', ctrl);
                  ctrl.$render();
              });
          }
      };  
  });
  </code></pre>
  
  <p>P.S. I have no idea what <code>restrict: 'A',</code> does - it's true cargo-cult programming at its worst.  The <code>require: 'ngModel',</code> seems necessary to populate the <code>ctrl</code> parameter.</p>
  
  <hr>
  
  <p>Inspired by the answer from @Dan Doyen, I rewrote it as:</p>
  
  <pre><code>app.directive('renderOnBlur', function() {
      return {
          require: 'ngModel',
          restrict: 'A',
          link: function(scope, elm, attrs, ctrl) {
              elm.bind('blur', function() {
                  var viewValue = ctrl.$modelValue;
                  for (var i in ctrl.$formatters) {
                      viewValue = ctrl.$formatters[i](viewValue);
                  }
                  ctrl.$viewValue = viewValue;
                  ctrl.$render();
              });
          }
      };  
  });
  </code></pre>
  
  <p>This has the benefit of being generic for any $formatter, rather than repeating the formatter code as in Dan's answer.</p>