19

I'm using a simple custom directive for a modified input field which occurs throughout my application:

app.directive('editor', function() {
    return {
        restrict: 'E',
        templateUrl: 'editor.html',
        scope: { value: '=' }
    };
});

The editor.html basically creates an input element with additional controls. Simplified it looks like this:

<div>
    <input ng-model="value">
    <!-- more code here -->
</div>

I access my directive using <editor value="{{object.name}}"></editor>. This works perfect. Now I need to perform different validations on the input. The necessary validators to use vary, so I would like to be able to pass the actual validators to my directive. Something like:

<editor value="{{object.name}}" validator-a validator-b></editor>

or

<editor value="{{object.name}}" validators="validatorA,validatorB"></editor>

How could I achieve that?

1 Answer 1

28

You are creating a custom input control, so you might as well support ng-model - which is the right thing to do.

And, validators - built-in and custom - only require: "ngModel" for their function and they are independent (by design) from the underlying DOM implementation, so having ng-model automatically supports all ng-model-based validators.

Having ng-model support will also make your directive participate in form validation.

Since you are using an existing directive inside the template (i.e. <input>), you don't even need to bother with DOM, as you would've had you built something from scratch.

app.directive("editor", function(){
  return {
    require: "?ngModel",
    scope: true,
    template: "<input ng-model='value' ng-change='onChange()'>",
    link: function(scope, element, attrs, ngModel){
      if (!ngModel) return;

      scope.onChange = function(){
        ngModel.$setViewValue(scope.value);
      };

      ngModel.$render = function(){
        scope.value = ngModel.$modelValue;
      };
    }
  };
});

Then you can just apply validators directly:

<editor ng-model="foo" minlength="3"></editor>

http://plnkr.co/edit/k21Oem6kT8SXUefyhbI6?p=preview

Sign up to request clarification or add additional context in comments.

2 Comments

That was essentially the solution with which I came finally up after some headbanging. Anyways, thank you for the very detailed explanation!
I added a fork to the link. When using the directive again it binds to the same ngModel for some reason. Using "scope.ngModel" instead seems to resolve the issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.