'Angular 12 - Character counter - Binding property input initialization of component in a directive
I am trying to build a "Character Counter" Angular directive for a custom component which I can't use ngModel to bind the value. (my-component shown below is really complex so, I ask to trust me and long term goal is to use the same directive thru different components). I have to intercept when the initialText input property is set, and of course when changedText is triggered
<my-component
characterCount
[initialText]="value"
(changedText)="valueChange.emit($event)">
</my-component>
@Input() initialText;
@Output() changedText: EventEmitter<string> = new EventEmitter<string>();
I have already figured out how to intercept changedText
@Directive({
selector: "[characterCount]",
})
...
@HostListener("changedText", ["$event"])
changeText(changedText){
this.setCharacterCount(changedText);
}
but I don't know how to intercept when the initialText property is set.
Thanks for your help guys.
Solution 1:[1]
Some time ago, in this SO someone ask about add a maxlength to a formControl
The same idea
@Component({
selector: 'app-help',
template: `<p class="count-help">{{_text}}</p>`,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./count.component.css']
})
export class CountComponent {
_text;
@Input() set text(value) {
if (value !== this._text) {
this._text = value;
this.cdr.detectChanges();
}
};
constructor(private cdr: ChangeDetectorRef) { }
}
And the directive
@Directive({
selector: '[characterCount]',
})
export class CountLengthDirective implements OnInit,OnDestroy {
ref: ComponentRef<CountComponent>;
subscription: any;
constructor(
@Self() private control: NgControl,
private el: ElementRef,
private vcr: ViewContainerRef,
private resolver: ComponentFactoryResolver
) {}
ngOnInit() {
const factory = this.resolver.resolveComponentFactory(CountComponent);
this.ref = this.vcr.createComponent(factory);
this.subscription = this.control.valueChanges
.pipe(startWith(this.control.value))
.subscribe((res) => {
this.ref.instance.text =this.control.value.length+' characters'
});
}
ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Eliseo |
