requiredDirective = function() {
  return {
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) return;
      attr.required = true; // force truthy in case we are on non input element

      var validator = function(value) {
        if (attr.required && ctrl.$isEmpty(value)) {
          ctrl.$setValidity('required', false);
          return;
        } else {
          ctrl.$setValidity('required', true);
          return value;
        }
      };

      ctrl.$formatters.push(validator);
      ctrl.$parsers.unshift(validator);

      attr.$observe('required', function() {
        validator(ctrl.$viewValue);
      });
    }
  };
}
@ngdoc directive
@name ng.directive:ngChange

@description
Evaluate the given expression when the user changes the input.
The expression is evaluated immediately, unlike the JavaScript onchange event
which only triggers at the end of a change (usually, when the user leaves the
form element or presses the return key).
The expression is not evaluated when the value change is coming from the model.

Note, this directive requires `ngModel` to be present.

@element input
@param {expression} ngChange {@link guide/expression Expression} to evaluate upon change
in input value.

@example
<doc:example>
  <doc:source>
    <script>
      function Controller($scope) {
        $scope.counter = 0;
        $scope.change = function() {
          $scope.counter++;
        };
      }
    </script>
    <div ng-controller="Controller">
      <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
      <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
      <label for="ng-change-example2">Confirmed</label><br />
      <tt>debug = {{confirmed}}</tt><br/>
      <tt>counter = {{counter}}</tt><br/>
    </div>
  </doc:source>
  <doc:protractor>
    var counter = element(by.binding('counter'));
    var debug = element(by.binding('confirmed'));

    it('should evaluate the expression if changing from view', function() {
      expect(counter.getText()).toContain('0');

      element(by.id('ng-change-example1')).click();

      expect(counter.getText()).toContain('1');
      expect(debug.getText()).toContain('true');
    });

    it('should not evaluate the expression if changing from model', function() {
      element(by.id('ng-change-example2')).click();
      expect(counter.getText()).toContain('0');
      expect(debug.getText()).toContain('true');
    });
  </doc:protractor>
</doc:example>