Don't even know the proper terminology to explain this problem
so, imagine this scenario...
There is a form-input-component and capturing some attributes and passing it down to the markup inside
<form-input placeholder="Enter your name" label="First name" [(ngModel)]="name" ngDefaultControl></form-input>
So, this is the markup, hope is pretty self explanatory...
obviously in the ts I have
@Input() label: string = '';
@Input() placeholder: string = '';
and then in the view I have something down these lines
<div class="form-group">
<label>{{label}}
<input type="text" [placeholder]="placeholder" [(ngModel)] = "ngModel">
</div>
Now, all works fine so far...
but let's say I want to add the validation rules around it...
or add other attributes that I don't capture via @Input()
How can I pass down anything else that comes down from <form-input>
to my <input>
in the view?
For the lazy ones:
export class FormInput implements OnInit {
@ViewChild(NgModel, {read: ElementRef}) inpElementRef: ElementRef;
constructor(
private elementRef: ElementRef
) {}
ngOnInit() {
const attributes = this.elementRef.nativeElement.attributes;
const inpAttributes = this.inpElementRef.nativeElement.attributes;
for (let i = 0; i < attributes.length; ++i) {
let attribute = attributes.item(i);
if (attribute.name === 'ngModel' ||
inpAttributes.getNamedItemNS(attribute.namespaceURI, attribute.name)
) {
continue;
}
this.inpElementRef.nativeElement.setAttributeNS(attribute.namespaceURI, attribute.name, attribute.value);
}
}
}
ngAfterViewInit
won't work if you nest multiple components which pass attributes, because ngAfterViewInit
will be called for inner elements before outer elements. I.e. the inner component will pass its attributes before it received attributes from the outer component, so the inner most element won't receive the attributes from the outer most element. That's why I'm using ngOnInit
here.