简体   繁体   中英

Do I always have to declare a variable in angular2 to get changes?

I have the following code:

This is the HTML view:

<button type="button" (click)="filterIt('male')">Filter male gender</button>
     <table>
       <ng-container *ngFor="let item of array;let i=index">
       <tr class="border-bottom" *ngIf="item.condition==condition_var">
         <td>{{i+1}}</td>
         <td>{{item.condition}}</td>
       </tr>
     </ng-container>
</table>

This is the typescript file (.ts):

  condition_var:string;
   filterIt(value){
     this.condition_var=value;
  }

NOTE: the array variable is already populated. (array of objects: [{}] )

My question is: Is it a practice in angular2 to always declare variables and to work with them in expressions, ngIf, ngFor etc. Or can I use a better way rather than populating my class with too many variables which doesn't look good.

To be more specific, is there a better way to write this code?

Yes there is a better (more idiomatic) way to do this: use a @Pipe .

import { Pipe, PipeTransform } from "@angular/core";

@Pipe({ name: 'filter' })
export class FilterPipe implements PipeTransform {
  transform(values: any, condition: any): any {
    return values.filter(item => item.condition === condition);
  }
}

Implement with:

<ng-container *ngFor="let item of array | filter:condition">

And set the condition however you like. Note that filters can accept more than one positional parameter, separated by colons.

Remember to add the pipe to whichever @NgModule s you use the pipe in:

import { FilterPipe } from 'pipes/fitler.pipe.ts';

@NgModule({
  declaractions: [
    FilterPipe
  ],
  // ...
})

And if the @NgModule in question is a lazy-loaded "shared" module, don't forget to re-export it:

@NgModule({
      declaractions: [
        FilterPipe
      ],
      exports: [
        FilterPipe
      ],
      // ...
    })

This answer is currently valid as of angular 4.3.6 .

I would use a getter inside your component class which filters the array you're looping over. Like this:

public myArray: any[] = [];
public myCondition: string | null = null;

public get myFilteredArray() {
  return this.myArray.filter(item => item.condition === this.myCondition);
}

And in your template just use the filteredArray:

<table>
  <tr class="border-bottom" *ngFor="let item of myFilteredArray;let i=index">
    <td>{{i+1}}</td>
    <td>{{item.condition}}</td>
  </tr>
</table>

Or you could build a pipe for it:

@Pipe({ name: 'myFilterPipe' })
export class MyFilterPipe implements PipeTransform {
  transform(value: any[], condition: string | null): any[] {
    if(!Array.isArray(value)) return [];
    return value.filter(item => item.condition === condition);
  }
}

In your case, you are filtering the data based on "male" string.

So you can directly use the following snippets:

*ngIf="item.condition=='male'"

don't need to make function, it will handle in if block ,

I would solve it this way:

//YOUR COMPONENT .TS CODE
filterIt(parameter: String){
//filter this.array here using your parameter
}

//YOUR COMPONENT .HTML CODE
<button type="button" (click)="filterIt('male')">Filter male gender</button>
 <table>
   <ng-container *ngFor="let item of array;">
   <tr class="border-bottom">
     <td>{{i+1}}</td>
     <td>{{item.condition}}</td>
   </tr>
 </ng-container>

This is much cleaner and let's the logic happen in your.ts file while your web page only displays.

Here is an approach if you want to avoid declaring the variable in your class. Just initialize variable on button click:

<button type="button" (click)="condition = 'male'">Filter male gender</button>
<table>
    <ng-container *ngFor="let item of array;let i=index">
        <tr class="border-bottom" *ngIf="item.condition == condition">
            <td>{{i+1}}</td>
            <td>{{item.condition}}</td>
        </tr>
    </ng-container>
</table>

You don't have to declare condition , condition_var or filterIt() method in your class in this way. Link to Plunker Demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM