markoffden
markoffden

Reputation: 1468

Angular 4 watch two way binding property change

I have created a toggle-sorting component which checks, if current sorting params are matching it's sorting slug, and handle clicks to output changes

// toggle-sorting.component.ts

@Input() sortingSlug: string;
@Input() currSorting: string;
@Output() currSortingChange: EventEmitter<string> = new EventEmitter<string>();

@HostBinding('class.sorting-asc') activeAsc: boolean;
@HostBinding('class.sorting-desc') activeDesc: boolean;

/**
 * Watch sorting params changes and update binding
 */
ngOnChanges() {
    this.activeDesc = this.currSorting === this.sortingSlug;
    this.activeAsc = this.currSorting === '-' + this.sortingSlug;
}

/**
 * Watch click event to set sorting
 */
@HostListener('click') setSorting() {
    if (this.activeDesc) {
        this.currSortingChange.emit('-' + this.sortingSlug);
    } else {
        this.currSortingChange.emit(this.sortingSlug);
    }
}

And I use it my parent component this way

// parent.component.html

// ... some layout
<th>
    <span toggle-sorting [(currSorting)]="sorting" sortingSlug="version">Scraper</span>
</th>
<th>
    <span toggle-sorting [(currSorting)]="sorting" sortingSlug="sites_count">Sites Scraped</span>
</th>
<th>
    <span toggle-sorting [(currSorting)]="sorting" sortingSlug="success_rate">Success rate</span>
</th>
// ... some layout

I have global sorting property in my parent component, which controls actual sorting param, which is two way binded to toggle-sorting children

// parent.component.ts

sorting: string = 'version';

I need to trigger api call each time global sorting param changes, but I cannot watch it with ngOnChanges as it's not @Input, I don't want to use ngDoCheck here as well (performancewise), and I do not want to use separate @Input and @Output in toggle-sorting (but for sure it will work for my purpose).

What is the best option in my case?

Upvotes: 3

Views: 4215

Answers (1)

kemsky
kemsky

Reputation: 15271

There are few ways to do that.

1 . Using full ngModel format:

  (ngModelChange)="onSortChanged($event)" [ngModel]="sorting"

  public onSortChanged(value:string):void
  {
     const changed = this._sorting !== value;
     this._sorting = value;
     if(changed) {
       //... do smth
     }
  }

2 . Using get/set:

private _sorting:string;

public get sorting():string
{
    return this._sorting;
}

public set sorting(value:string)
{
    const changed = this._sorting !== value;
    this._sorting = value;
    if(changed) {
       this.onSortingChanged();
    }
}

Upvotes: 7

Related Questions