0

Hi I am trying to create a simple grid with sorting feature using Angular 2. Below is the structure of the component.

import {Component, Pipe} from 'angular2/core';
import {NgClass} from 'angular2/common';

    @Component({
        selector: "sorter",
        template: `
            <i class="indicator glyphicon glyphicon glyphicon-sort-by-alphabet"  [ngClass]="{'glyphicon-sort-by-alphabet-alt': isReverse}"></i>
            <span>{{isReverse}}</span>
        `,
        directives: [NgClass]
    })
    export class Sorter {
        isReverse = true;
        public sortData(key) {
            this.isReverse = !this.isReverse;
            console.log("Directection-->" + this.isReverse);
        }

    }

I have created a var isReverse and changing it in the the sortData() method. The console.log() prints the correct value when I click the column header but it is not affecting the template. I am unable to figure what is going wrong here.

Thanks

3
  • Where is sortData() called from? Do you call this from non-Angular code? Commented Jan 22, 2016 at 11:47
  • 1
    Whats the issue? is there any problem with ngClass? If so, check in browser's console at runtime. Go to particular element and do your stuff and check weather class gets applied or not.... and make sure glyphicon-sort-by-alphabet-alt is correct class name. Commented Jan 22, 2016 at 12:48
  • Yes the class name is correct. But I want that to be applied on the change of isReverse value. The sort data method is invoked form outside. That is on the click of <th> element which works as a column. The Sorter is just a icon that needs to be changed when sorting applied. Commented Jan 25, 2016 at 6:16

2 Answers 2

3

If your view is not updating (e.g., {{isReverse}} doesn't change), you are probably calling sortData() from "outside" Angular, hence Angular is not automatically running change detection when your click handler finishes.

One way to solve this is to inject ChangeDetectorRef and force it to run change detection on this component:

import {Component, Pipe, ChangeDetectorRef} from 'angular2/core';
export class Sorter {
   constructor(_cdRef: ChangeDetectorRef) {}
   public sortData(key) {
    this.isReverse = !this.isReverse;
    console.log("Directection-->" + this.isReverse);
    this._cdRef.detectChanges();
  }
  ...

See also Triggering Angular2 change detection manually

Sign up to request clarification or add additional context in comments.

Comments

1

From what I understand from your question and your code, it seems that you create a dedicated component to change sorting.

So the isReverse attribute is internally to this component and can't be used outside it. To make this possible and leveraging two way binding, I would suggest to refactor your component as described below:

@Component({
  selector: "sorter",
  template: `
    <i class="indicator glyphicon glyphicon glyphicon-sort-by-alphabet"  
       [ngClass]="{'glyphicon-sort-by-alphabet-alt': isReverse}"
       (click)="sortData()"></i>
    <span>{{isReverse}}</span>
  `,
  directives: [NgClass]
})
export class Sorter {
  @Input()
  isReverse = true;
  @Output()
  isReverseChanged:EventEmitter = new EventEmitter();

  public sortData(key) {
    this.isReverse = !this.isReverse;
    console.log("Directection-->" + this.isReverse);
    this.isReverseChanged.emit(this.isReverse);
  }
}

In the grid component you can now have access to the isReverse property, as described below:

<sorter [(isReverse)]="tableReverse"></sorter>

This way you can sort the grid according to the tableReverse property of this parent component.

Hope it helps you, Thierry

Comments

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.