Reputation: 1988
For example, the Angular documentation here uses the following directive for the forbiddenName validation:
@Directive({
selector: '[appForbiddenName]',
providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
})
export class ForbiddenValidatorDirective implements Validator {
@Input('appForbiddenName') forbiddenName: string;
validate(control: AbstractControl): {[key: string]: any} {
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
: null;
}
}
Is it possible to use a @Input of say Object
or string[]
instead of only allowing strings? If not, how do you pass in multiple arguments?
The Angular docs uses it in the example as such:
<input id="name" name="name" class="form-control"
required minlength="4" appForbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
Upvotes: 3
Views: 3982
Reputation: 60596
Multiple strings with a separator
You can pass multiple strings with a separator.
For example, I defined a range validator as follows:
<input class="form-control"
id="inputStarRating"
type="text"
placeholder="Rating"
mhRange="1,5"
[(ngModel)] = "movie.starRating"
name="starRating"
#starRatingVar = "ngModel" />
The directive then had code as follows:
constructor(@Attribute('mhRange') range: string) {
const arr = range.split(',');
let min = 1;
let max = 10;
if (arr[0]) { min = parseInt(arr[0], 10); }
if (arr[1]) { max = parseInt(arr[1], 10); }
this.validator = NumberValidators.range(min, max);
}
Notice that this uses a split to pull apart the two different values.
Arrays
You can also pass arrays like this:
@Input('appForbiddenName') forbiddenName: string[];
validate(control: AbstractControl): {[key: string]: any} {
console.log(this.forbiddenName);
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName[0], 'i'))(control)
: null;
}
NOTE: To minimize changes in the above code, I just checked the first element. But you could change it to loop through the array.
The HTML then looks like this:
<input id="name" name="name" class="form-control"
required minlength="4" [appForbiddenName]="powers"
[(ngModel)]="hero.name" #name="ngModel" >
Notice how it uses binding to bind to the array of values.
Objects
You can define objects like this:
@Input('appForbiddenName') forbiddenName: Hero;
validate(control: AbstractControl): {[key: string]: any} {
console.log(this.forbiddenName);
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName.alterEgo, 'i'))(control)
: null;
}
Assuming there is a type Hero
defined. For the sample app from the documentation, I had to use any
because no Hero
type was defined.
The HTML then looks like this:
<input id="name" name="name" class="form-control"
required minlength="4" [appForbiddenName]="hero"
[(ngModel)]="hero.name" #name="ngModel" >
Bottom line, you cannot pass anything but a string to the attribute, but that string can be a binding.
So doing something like this:
appForbiddenName='{"name":"Dr.", "alterEgo":"Dr. What", "power":"test"}'
Just provides it as a string. You'd have to write the code to parse it and turn it back into an object:
@Input('appForbiddenName') forbiddenName: string;
validate(control: AbstractControl): {[key: string]: any} {
const hero: Hero = JSON.parse(this.forbiddenName);
console.log(hero.alterEgo);
return this.forbiddenName ? forbiddenNameValidator(new RegExp(hero.alterEgo, 'i'))(control)
: null;
}
Upvotes: 4