Как отфильтровать результаты для ползунка диапазона с несколькими флажками вместе в Angular 2? - PullRequest
0 голосов
/ 01 января 2019

Я пытаюсь отфильтровать результаты для данного массива "db", есть три фильтра: цена, продолжительность и категория.

Я пытался использовать метод filter () для фильтрации результатов.

Вот ссылка на код, который я пробовал: https://stackblitz.com/edit/multiple-filters?file=app%2Fapp.component.ts

component.html

<div class="filters">
  <div id="price">
  <h3>Price: {{rangeValues[0] + ' - ' + rangeValues[1]}}</h3>
  <p-slider [(ngModel)]="rangeValues" (click)="handleChange()" [min]="0" 
  [max]="2000" [style]="{'width':'14em'}" [range]="true"></p-slider>
</div>
<hr>
<div id="duration">
    <h3>Duration</h3>
    <li><input type="checkbox" (click)="checkFilter('2 days')"> 2 Days</li>
    <li><input type="checkbox" (click)="checkFilter('6 days')">6 Days</li>
</div>
<hr>
<div id="Theme">
    <h3>Theme</h3>
    <li><input type="checkbox" id="Wild Life" (click)="filterTheme('Wild Life')">Wild Life</li>
    <li><input type="checkbox" id="Romance" (click)="filterTheme('Romance')">Romance</li>
    <li><input type="checkbox" id="Food & Drink" (click)="filterTheme('Food & Drink')">Food & Drink</li>
    <li><input type="checkbox" id="Adventure" (click)="filterTheme('Adventure')">Adventure</li>
 </div>
 <hr>
 </div>

 <div class="results">
    <h3>Results</h3>

    <div *ngFor="let p of package">
    <p>{{p.product_name}}</p>
    </div>
 </div>

component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
 db=[
{
  "id":"1",
  "product_name":"6 Days at Karnataka",
  "price":324,
  "duration":"6 days",
  "category":["Romance"]
},
{
  "id":"5",
  "product_name":"2 Days at Thailand",
  "price":234,
  "duration":"2 days",
  "category":["Romance","Wild Life"]
},
{
  "id":"8",
  "product_name":"2 Days at Delhi",
  "price":1400,
  "duration":"2 days",
  "category": ["Romance","Food & Drink","Adventure"],
}
];
rangeValues: number[] = [0,2000];
package:any;
filterData=[];


ngOnInit(){
  this.packageList();
}

packageList(){
 for(let i = 0; i < this.db.length; i++){
  this.filterData.push(this.db[i]);
  this.package =this.filterData;
 }    
}

handleChange() {
        for(let i = 0; i < this.filterData.length; i++){             
          this.package= this.filterData.filter(item => item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
   }
}

checkFilter(id){ 
    if(id.checked==true){
      for(let i = 0; i < this.filterData.length; i++){
         this.filterData= this.filterData.filter(item => item.duration !== id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          this.package=this.filterData;
      }
    }
    else {
      for(let i = 0; i < this.filterData.length; i++){
          this.filterData= this.filterData.filter(item => item.duration == id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          this.package=this.filterData;
      }
    }
 }


filterTheme(id){
    let b=(<HTMLInputElement>document.getElementById(id));
    if(b.checked==true){
      for(let i = 0; i < this.filterData.length; i++){
        for(let j=0;j< this.filterData[i].category.length; j++){
          if(this.filterData[i].category[j]==id &&  this.filterData[i].price >=this.rangeValues[0] &&  this.filterData[i].price <=this.rangeValues[1]){

            this.package= this.filterData.filter(item => item.category[j]==id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          }
        }
      }
    }else {
      for(let i = 0; i < this.filterData.length; i++){
        for(let j=0;j<this.filterData[i].category.length; j++){
          if(this.filterData[i].category[j]!==id && this.filterData[i].price >=this.rangeValues[0] && this.filterData[i].price <=this.rangeValues[1]){
            this.package = this.filterData.filter(item => item.category[j]!== id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);

          }
        }
      }
    }

 }

}

Что я хочудостигнуть:

  1. фильтр цен: , который я использовал ползунок диапазона для фильтрации результатов, и он корректно фильтрует цену, но он также должен фильтровать результатыдля выбранной продолжительности и категории.

  2. Фильтр продолжительности: использовал флажок для фильтрации результатов, это должно отфильтровать результаты по заданной цене и выбралКатегория.

  3. Фильтр категории: одно имя_продукта может иметь одну или несколько категорий, и оно должно фильтровать результаты по выбранной и выбранной цене.

1 Ответ

0 голосов
/ 01 января 2019

Что ж, вы усложняете ситуацию, зацикливаясь на ней и проверяя ее, у вас может быть одна функция, которая будет работать за вас.

step1: Взять 3 модели

rangeValues: number[] = [0, 2000];
  durations: any = [];
  themes: any = [];

step2 : назначить значения пользователя в этих моделях

  handleChange() {
    this.ApplyFilters();
  }

  checkFilter(id) {
    if (this.durations.some(a => a === id)) {
      this.durations = this.durations.filter(a => a !== id)
    } else {
      this.durations.push(id)
    }
    this.ApplyFilters();
  }


  filterTheme(id) {
    if (this.themes.some(a => a === id)) {
      this.themes = this.themes.filter(a => a !== id)
    } else {
      this.themes.push(id)
    }
    this.ApplyFilters();
  }

step3 : создать один общий фильтр

  ApplyFilters() {
    this.package = this.filterData.filter(item => {
      return (item.price >= this.rangeValues[0] && item.price <= this.rangeValues[1]) && (this.durations.some(b => b === item.duration) || this.durations.length === 0) && (item.category.every(c => this.themes.some(d => d === c)) || this.themes.length === 0)
    });
  }

И все готово

Вот демоверсия

...