0

I built a custom directive for input elements. It is a search directive that given an items input returns an output with these items filtered based on the search string.

<input pieSearch placeholder='Search' [attribute]='"label"' [formControl]='search'
        [items]='widgetOfSelectedType' (filterEvent)='filterWidgets($event)'>

Under the hood, I am simply using a Hostlistener and then calling a pipe. As such:

@HostListener('keyup', ['$event.target.value']) onKeyUp(value) {
  this.searchTerm = value;
  this.applyFilter();
}

That works well for everything expect when I want to reset my input this.search.reset(). Which makes sense, as this isn't a user typing in the input field it isn't caught by the Hostlistener.

So my question to you all, is how would you go about doing that?

1
  • You can implement the event change for this behavior Commented Mar 28, 2018 at 11:21

1 Answer 1

1

I've created a simple resetSpy directive for you. You can inject NgControl directive to get access to the underlying FormControl directive.

Then it's just a matter of creating our own reset stream. We are mapping the form value changes to its pristine status. If the control goes from not pristine to pristine, it means that the form was reset.

Live demo

import { Directive, Output, EventEmitter } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import {map, pairwise, startWith, filter} from 'rxjs/operators';

@Directive({
  selector: '[resetSpy]',
})
export class ResetSpyDirective  {
  @Output() reset = new EventEmitter<void>();

  subscription: Subscription;

  constructor(private ngControl: NgControl) {  }

  ngOnInit() {
    const reset$ = this.ngControl.control.valueChanges.pipe(
      map(v => this.ngControl.pristine),
      startWith(this.ngControl.pristine),
      pairwise(),
      filter(([from, to]) => !from && to)
    );

    this.subscription = reset$.subscribe(() => this.reset.emit());
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for putting in the effort of creating this directive. In the end, I am going to do something slightly different. I am going to replace my HostListener with your ngControl.control.valueChanges. Thanks for the tip!
Glad I could help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.