Angular 4 - How to get a pipe to trigger on a programmatic value change (no keyboard events)

3.4k Views Asked by At

This is my first angualr project. I am updating an inputs value on an elements click. I would like to trigger the filtering pipe when this value is changed. The logic to trigger the pipe is in a directive. Is this possible?

Component

<input id="filter-careers" placeholder="type your title here" type="text" [(ngModel)]="term" value="">

 <div class="vacancy {{vacancy.department}}" *ngFor="let vacancy of vacancies | filter:term"
       (click)="openModalContent(vacancy.description, vacancy.positionTitle, vacancy.department, vacancy.link)">
      <p>{{vacancy.positionTitle }}</p>
  </div>

Second component

<div class="department" *ngFor="let department of departments" appDepartmentsDirective [departmentName]="department.name" >

      <div class="icon" [ngStyle]="{background: 'url(' + '../../assets/' + department.link + '.png' + ') center center no-repeat'}">
        <img src="../../assets/{{department.link}}.svg" />
      </div>
    </div>

Directive

import { Directive, HostListener, Input  } from '@angular/core';

@Directive({
  selector: '[appDepartmentsDirective]'
})

export class DepartmentsDirectiveDirective {

  @Input() departmentName:string;

  constructor() { }



  @HostListener('click') click() {
    console.log('department name: ' + this.departmentName);
    if((<HTMLInputElement>document.getElementById('filter-careers'))){
      console.log('do something here to trigger the filtering');

      (<HTMLInputElement>document.getElementById('filter-careers')).value = this.departmentName;
      (<HTMLInputElement>document.getElementById('filter-careers')).focus();

    }
    else{
      console.log('do something else');
    }

  }

}
1

There are 1 best solutions below

2
On

By default, a pipe is only re-executed if the passed value or parameters change. If the value or parameters are objects, only different object instances are recognized as change, adding/removing values from an array or modifying properties of an object are not recognized.

If you make the pipe impure, it is executed every time change detection runs. This can cause serious performance issues.

A simple trick is to pass an additional parameters to the pipe like

*ngFor="let vacancy of vacancies | filter:term:dummy"

and every time you want the pipe to be re-executed, modify dummy

dummy:number = 0;

someHandler() {
  this.vacancies.push(someValue);
  this.dummy++;
}