Let's say I have a very basic component that adds functionality to a given text. For example:
@Component({
selector: 'app-clickable-key',
template: '<span (click)="doSomething()">{{ key }}</span>',
styleUrls: ['./translated-text.component.scss']
})
export class TranslatedTextComponent {
@Input() key: string;
doSomething(): void {
this.key = `${this.key} clicked!`;
}
}
Usage would be:
<app-clickable-key key="Hello!"></app-clickable-key>
Now I would like to append the above functionality not only to tree nodes but also to attribute values:
<3rd-party-input customLabel="How to make this clickable as well?"></3rd-party-input>
...Which is essentially just a wrapper of a label
(<label>{{ customLabel }}</label>
)
If this functionality was only for a transformation of the text, then I would be able to use pipes, but in this case, I need to change the template of that placeholder. Is that somehow possible?
CodePudding user response:
This seems to be adding behavior to the element. For such a case, I would suggest you extract your functionality in a reusable Directive. The behavior can be attached to any DOM easily.
A directive can be pretty simple, it can use textContent
HostBinding
decorator, and returned value will be set to DOM node innerText
. Just make sure while using directive pass attribute value to it. For eg clickable="key"
indicate a directive to read the initial value from key
attribute.
Directive
@Directive({
selector: '[clickable]',
})
export class ClickableTextComponent {
@Input() clickable: string;
private text = '';
constructor(private el: ElementRef) {}
@HostBinding('textContent') get textContent() {
return this.text;
}
@HostListener('click')
doSomething(): void {
this.text = `${this.text} clicked!`;
}
ngOnInit() {
this.text = this.el.nativeElement.getAttribute(this.clickable);
}
}
Usage
<span
clickable="key"
key="Something is funny">
</span>
<hr />
<label
clickable="customLabel"
customLabel="This is label working with Directive"
>
</label>
CodePudding user response:
For that you can use the control value accessor
<app-custom-input
label="My Custom label"
[(ngModel)]="inputOne"
></app-custom-input>
Create component with providers
@Component({
selector: 'app-custom-input',
templateUrl: './custom-input.component.html',
styleUrls: ['./custom-input.component.scss'],
// Step 1: copy paste this providers property
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}
]
})
Here is complete example