问题
I am trying to filter results for the given array "db", there are three filters: price, duration, and category.
I tried using filter() method to filter results.
Here is the link of code which i have tried: 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]);
}
}
}
}
}
}
What I want to achieve:
price filter: which I have used the range slider to filter results and it filters price correctly but it should also filter results for selected duration and category.
Duration filter: used the checkbox to filter results, this should filter results for the given price and selected category.
Category filter: one product_name can have one or more category and it should filter results for the selected one and price chosen.
回答1:
Well, you are complicating the things by looping over it and checking it you can have one function that would do the work for you.
step1: Take 3 models
rangeValues: number[] = [0, 2000];
durations: any = [];
themes: any = [];
step2: assign the values of the user in these models
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: Create one common filter
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)
});
}
And your are done
Here is the demo
来源:https://stackoverflow.com/questions/53994077/how-to-filter-results-for-range-slider-with-multiple-checkbox-together-in-angula