frameBrandとframeColorの2つの異なるカテゴリ(できればそれ以上)を使用して、より複雑な(私にとって)フィルターを実行しようとしています。特定のブランドに絞り込み、それらの結果を使用して、より具体的で狭い検索ができるまで色をフィルタリングしたいと思います。2つのカテゴリのフィルタリングに苦労しています
以下のJSONの例では、ブランドのチェックボックスをクリックして「anne klein」フレームを取得し、次に色のチェックボックス「brown」をクリックして「anneklein-brown」フレームを表示したいと思います。それぞれ異なる「カテゴリ」からの2つのチェックボックス。理想的には、これを拡張して、価格のチェックボックスなどの他のカテゴリを使用できるようにします。StackOverflowを使用して.filterを使用して現在の場所を取得しましたが、Angularを使用した複数のカテゴリとチェックボックスではあまり見ていません。
{
"frames": [
{
"frameBrand": "altair",
"frameColor": "Black",
"frameId": 1,
"frameName": "A5052",
"releaseDate": "05-01-2021",
"framePrice": 25,
"frameDescription": "this is an altair frame.",
"imageUrl": "/assets/images/frames/ALO/A5052/A5052_001_LG_01.jpg",
"categories": [1]
},
{
"frameBrand": "anne klein",
"frameColor": "Ruby",
"frameId": 2,
"frameName": "AK5091",
"releaseDate": "05-01-2021",
"framePrice": 45,
"frameDescription": "this is an anne klein frame.",
"imageUrl": "/assets/images/frames/AKO/AK5091/AK5091_610_LG_01.jpg",
"categories": [2]
},
{
"frameBrand": "anne klein",
"frameColor": "Brown",
"frameId": 3,
"frameName": "AK5090",
"releaseDate": "05-01-2021",
"framePrice": 45,
"frameDescription": "this is an anne klein frame.",
"imageUrl": "/assets/images/frames/AKO/AK5090/AK5090_200_LG_01.jpg",
"categories": [2]
},
{
"frameBrand": "bebe",
"frameColor": "Silver",
"frameId": 4,
"frameName": "BB5192",
"releaseDate": "05-01-2021",
"framePrice": 40,
"frameDescription": "this is an bebe frame.",
"imageUrl": "/assets/images/frames/BBO/BB5192/BB5192_001_LG_01.jpg",
"categories": [3]
}
]
}
私のTSファイルには、filterFramesByBrand、filterFramesByColor、filterResultsの3つの関数があります。(change)= "filterFramesByBrand($ event)"が発生したときに、ブランドと色からチェックボックスをオンにして、formGroup内の別の配列にプッシュします。次に、魔法を起こそうとしているfilterResults関数を実行します。期待どおりにブランドをフィルタリングするようになりましたが、2つのカテゴリ(ブランドと色)を組み合わせると困惑します。filterResults関数のcolorセクションは、何らかの理由でbrandsセクションのように機能しないため、コメントアウトしました。
checkboxForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.checkboxForm = this.fb.group({
brandCheckArray: this.fb.array([]),
colorCheckArray: this.fb.array([])
});
}
filteredFrames: IFrames[] = [...this.frames];
filterFramesByBrand(category) {
const brandCheckArray: FormArray = this.checkboxForm.get(
"brandCheckArray"
) as FormArray;
if (category.target.checked) {
brandCheckArray.push(new FormControl(category.target.value));
} else {
let i: number = 0;
brandCheckArray.controls.forEach((item: FormControl) => {
if (item.value == category.target.value) {
brandCheckArray.removeAt(i);
return;
}
i++;
});
}
this.filterResults();
}
filterFramesByColor(category) {
const colorCheckArray: FormArray = this.checkboxForm.get(
"colorCheckArray"
) as FormArray;
if (category.target.checked) {
colorCheckArray.push(new FormControl(category.target.value));
} else {
let i: number = 0;
colorCheckArray.controls.forEach((item: FormControl) => {
if (item.value == category.target.value) {
colorCheckArray.removeAt(i);
return;
}
i++;
});
}
this.filterResults();
}
filterResults() {
this.filteredFrames = this.frames.filter(el => {
let frameBrandEl = el.frameBrand
.split(" ")
.join("")
.toLowerCase();
// let frameColorsEl = el.frameColor
// .split(" ")
// .join("")
// .toLowerCase();
let brandsChecked = this.checkboxForm.get("brandCheckArray").value;
// let colorsChecked = this.checkboxForm.get("colorCheckArray").value;
var fixCheckedBrands = brandsChecked.map(v =>
v
.split(" ")
.join("")
.toLowerCase()
);
// var fixCheckedColors = colorsChecked.map(v =>
// v
// .split(" ")
// .join("")
// .toLowerCase()
// );
console.log(frameBrandEl);
// console.log(frameColorsEl);
console.log(fixCheckedBrands);
// console.log(fixCheckedColors);
return frameBrandEl.includes(fixCheckedBrands);
// return frameColorsEl.includes(fixCheckedColors);
});
// if there are no checked checkboxes - show all
if (this.checkboxForm.value.brandCheckArray.length === 0) {
this.filteredFrames = this.frames;
}
}
最後に:ここで私のStackBlitzへのリンクです- https://stackblitz.com/edit/angular-ivy-product-filters?file=src%2Fapp%2Fproduct-filter.ts私は.filterに関するガイダンスのビットを考えます機能私はこれを理解することができました。ヘルプや提案をありがとう。
私はあなたの論理を単純化します。これをFormGroup
ofで行う代わりにFormArrays
(それが要件でない限り)、ここでの最善の方法FilterComponent
は、入力として模範的なオブジェクトを受け入れるものを作成することtype CheckboxFilter = { name: string, isChecked: boolean }
です。おそらく、必要にid
応じて追加できます。それを作成してもらうOutput
と、に追加されますFilterComponent
。今、あなたはそのためのハンドラに追加BrandChanged
してColorChanged
。これに基づいて、選択したフィルターを保存し、フレームに適用することができます。
それはあなたがそれをより反応的な方法にすることさえ可能にします。あなたは両方のBehaviourSubject<string[]>
ためにdecalreすることができました、Brand
そしてColor
、イベントがあるとあなたは主題を操作することができました。後でcombainLatest
、JSONファイルまたはAPIから取得して適用したフレームだけを、次のように実行します。
combineLatest([frames$, brands$, colors$]).pipe(filter([frames, brands, colors]) => ...)
これが作業中のstackblitzです
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加