Starfish
Starfish

Reputation: 3574

Checkbox filtering only works on refresh Angular2

So for easy usability I want to add checkboxes as filters. However, it only loads when I refresh the page.

These are my files:

filename.component.ts

import { Component } from '@angular/core';
import { CheckboxFilterPipe } from './checkbox-filter.pipe';

@Component({
    templateUrl: 'app/filename.component.html',
    pipes: [CheckboxFilterPipe]
})

export class filenameComponent {
    checkboxes: any[] = [{
        id: 1,
        label: 'Filter 1',
        state: true
    }, {
        id: 2,
        label: 'Filter 2',
        state: true
    }];

    displayData: any[] = [
        // Objects I want to display
    ];
}

checkbox-filter.pipe.ts

import { Pipe, Pipetransform } from '@angular/core';

@Pipe({
    name: 'CheckboxFilter'
})

export class CheckboxFilterPipe implements PipeTransform {
    transform(values: any[], args: string[]): boolean {
        console.log(args);
        return values.filter(value=> {
            // My filtercode, return true for now
            return true;
        });
    }
}

filename.component.html

<div class="content-wrapper">
    <div class="row">
        <label *ngFor="let cb of checkboxes">
            <input type="checkbox" [(ngModel)]="cb.state"> {{cb.label}}
        </label>
    </div>
</div>
<table>
    <tr *ngFor="let value of displayData | CheckboxFilter:checkboxes">
        <td>{{ value.value1 }}</td>
        <td>{{ value.value2 }}</td>
        <td>{{ value.value2 }}</td>
    </tr>
</table>

I'm using Angular2.rc.0. I've renamed my variables in this question for clarity. The output in the console only happens when I refresh the page, not when I (un)check the checkboxes. Any help to resolve this issue is appreciated.

Upvotes: 2

Views: 1162

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657456

Angulars change detection doesn't check the content of objects, only the object references itself, therefore Angular doesn't recognize the updated state in checkboxes and as long as dependent values haven't changed, Angular doesn't call the pipe again.

To work around you can make the pipe impure:

@Pipe({
    name: 'CheckboxFilter',
    pure: false
})

This way Angular calls the pipe every time change detection is run, which is quite often, therefore this can become expensive.

Alternatively you can make Angular to recognize the change by creating a copy of the array

<input type="checkbox" [(ngModel)]="cb.state"
    (ngModelChange)="forceUpdateCheckboxes()"> {{cb.label}}

forceUpdateCheckboxes() { this.checkboxes = this.checkboxes.slice(); }

Plunker example

Upvotes: 4

Related Questions