У меня такой код:

Это вид HTML:

<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>

Это файл машинописного текста (.ts):

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

ПРИМЕЧАНИЕ. переменная array уже заполнена. (массив объектов: [{}] )

Мой вопрос: практикуется ли angular2 всегда объявлять переменные и работать с ними в выражениях, ngIf, ngFor и т. Д. Или я могу использовать лучший способ, вместо того, чтобы заполнять мой класс слишком большим количеством переменных, что выглядит не очень хорошо.

Чтобы быть более конкретным, есть ли лучший способ написать этот код?

3
masterach 28 Авг 2017 в 15:26

5 ответов

Лучший ответ

Да, есть лучший (более идиоматический) способ сделать это: использовать @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);
  }
}

Реализуйте с помощью:

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

И установите condition так, как вам нравится. Обратите внимание, что фильтры могут принимать более одного позиционного параметра, разделенных двоеточиями.

Не забудьте добавить канал к @NgModule, в котором вы используете канал:

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

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

И если рассматриваемый @NgModule является загруженным «ленивым» модулем с отложенной загрузкой, не забудьте реэкспортировать его:

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

Этот ответ в настоящее время действителен как угловой 4.3.6.

1
msanford 28 Авг 2017 в 15:33

Я бы использовал геттер внутри вашего класса компонентов, который фильтрует массив, над которым вы зацикливаетесь. Как это:

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

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

И в вашем шаблоне просто используйте фильтрованный массив:

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

Или вы можете построить трубу для этого:

@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);
  }
}
1
cyr_x 28 Авг 2017 в 13:10

Я бы решил это так:

//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>

Это намного чище, и пусть логика происходит в вашем файле .ts, а ваша веб-страница только отображается.

0
sander 28 Авг 2017 в 12:57

В вашем случае вы фильтруете данные по "мужской" строке.

Таким образом, вы можете напрямую использовать следующие фрагменты:

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

Не нужно делать функцию, она будет обрабатывать в , если блок ,

0
Kunvar Singh 28 Авг 2017 в 12:33

Вот подход, если вы хотите избежать объявления переменной в вашем классе. Просто инициализируйте переменную по нажатию кнопки:

<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>

Вам не нужно объявлять метод condition, condition_var или filterIt() в вашем классе таким образом. Ссылка на демонстрационную версию Plunker.

0
Faisal 28 Авг 2017 в 13:43