Filter Daftar Berdasarkan Kategori - Angular 8

Saya memiliki daftar dari firebase yang ingin saya filter dan menampilkan spesialisasi di bawah setiap kategori. Ketika saya melakukan log konsol, kategori dan spesialisasi diambil, tetapi saya tidak tahu apa yang perlu saya lakukan untuk merender spesialisasi di UI ketika kategori dipilih. Bimbingan apa pun akan dihargai. Terima kasih. Di bawah ini adalah pekerjaan saya:

Keluaran Proyek

Desain Koleksi Basis Data

kategori.JSON

{ "-Lq2PAU_P-fPniAMrQ85" : { "name" : "test" }, "accountingFinance" : { "name" : "Akuntansi dan Keuangan" }, "assuranceAudit" : { "name" : "Assurance dan Audit" }, "Manajemen risiko" : { "nama" : "Manajemen Risiko" }, "pajak" : { "nama" : "Perpajakan" } }

kategori.JSON

{
  "accountingFinance" : [ null, "Accounting Management Information Systems", "Accounting Records Maintenance", "Accounts Preparation", "Accountancy / Finance Training" ],
  "assuranceAudit" : [ null, "Asset Management Review", "Assurance / Audit Training", "Climate Change / Sustainability Audit", "Enviromental Audit" ],
  "riskManagement" : [ null, "Acturial Service", "Enterprise Risk Management", "Fraud Risk Management", "Political Risk Management" ],
  "taxation" : [ null, "Business Income Tax", "Capital Gains Tax", "Corporation Tax", "Employee Tax (PAYE)", "Export Incentives" ]
}

Markup HTML

<div class="row">
                            <div class="col-4">
                                <div class="list-group">
                                    <a 
                                        *ngFor="let c of (category$ | async)" 
                                        routerLink="/admin/expert-category" [queryParams]="{ category: c.key }"
                                        class="list-group-item list-group-item-action"
                                        [class.active]="category === c.key">
                                        {{ c.name }}
                                    </a>
                                </div>
                            </div>
                            <div class="col">
                                <div class="row">
                                    <ng-container *ngFor="let categories of filteredCategories; let i = index">
                                        <div class="col">
                                            <div class="card">
                                                <!--<div class="card-body">-->
                                                    <ul class="list-group list-group-horizontal">
                                                        <li class="list-group-item">{{ categories }}</li>
                                                    </ul>
                                                <!--/div>-->
                                            </div>
                                        </div>
                                        <div  *ngIf="(i+1) % 4 === 0" class="-w-100"></div>
                                    </ng-container>     
                                </div>
                            </div>
                        </div>

Layanan.ts

getCategories(): Observable<any[]> {
    return this.db.list('/categories')
    .snapshotChanges().pipe(
      map(actions =>
        actions.map(data => ({ key: data.key, ...data.payload.val() }))
    ));
  }

  getAll(): Observable<any[]> {
    return this.db.list('/category')
    .snapshotChanges().pipe(
      map(category =>
        category.map(cat => {
            const key = cat.key;
            const payload = cat.payload.val();
            return { key, ...payload };
          })),
        );
  }

File komponen.ts

export class ExpertCategoryComponent implements OnInit {
  category$;
  category: string;
  closeResult: string;
  filteredCategories: any[] = [];
  specialization: any[] = [];

  constructor(
    private categoryService: CategoryService,
    route: ActivatedRoute,
    private router: Router,
    private modalService: NgbModal) {

      this.categoryService.getCategories().subscribe(specialization => {
        this.specialization = specialization;
        console.log(this.specialization);
        route.queryParamMap.subscribe(params => {
          this.category = params.get('category');

          this.filteredCategories = (this.category) ? this.specialization.filter(s => s.category === this.category) : this.specialization;
          console.log(this.filteredCategories);
          });
      });

      this.category$ = this.categoryService.getAll();
  }

Saya tidak mendapatkan kesalahan apa pun saat ini kecuali array kosong di konsol ketika saya memilih kategori.


person E. Ogony    schedule 04.10.2019    source sumber
comment
Cara terbaik adalah menggunakan pipa khusus untuk memfilter apa pun.   -  person Mises    schedule 04.10.2019
comment
@Mises Tidak menurut dokumentasinya: angular.io/guide/pipes# lampiran-tanpa-pipa filter-atau-urutan demi pipa   -  person peinearydevelopment    schedule 04.10.2019
comment
Saya tidak melihat category dalam contoh JSON Anda tetapi Anda menggunakannya di (s.category)   -  person Maihan Nijat    schedule 04.10.2019
comment
bitbucket.org/ mises543/sorting-list/src/master/src/app/shared/ pipa ini diurutkan berdasarkan Kategori/Kueri/Urutkan menurut abjad berdasarkan judul dan waktu.   -  person Mises    schedule 04.10.2019
comment
@peinearydevelopment Pipa khusus bukanlah pipa yang semuanya dibuat.   -  person Mises    schedule 04.10.2019
comment
@peinearydevelopment Bekerja, lihat? sorting-list-angular.web.app/library   -  person Mises    schedule 04.10.2019
comment
Berapa banyak item yang kita harapkan melalui panggilan ini?   -  person Saksham    schedule 04.10.2019
comment
Saya sebenarnya menerapkan apa yang telah saya pelajari dari tutorial di proyek saya sendiri. Saya seorang pemula dalam hal ini, jadi silakan jelaskan kepada saya jika saya lambat. Ini adalah contoh JSON kedua saya untuk s.category   -  person E. Ogony    schedule 04.10.2019
comment
{ -Lq2PAU_P-fPniAMrQ85 : { nama : tes }, akuntansiKeuangan : { nama : Akuntansi dan Keuangan }, jaminanAudit : { nama : Penjaminan dan Audit }, Manajemen risiko : { nama : Manajemen Risiko }, perpajakan : { nama : Perpajakan } }   -  person E. Ogony    schedule 04.10.2019
comment
Saya minta maaf atas format kode yang buruk. Bagaimana cara memformat kode dalam komentar?   -  person E. Ogony    schedule 04.10.2019
comment
@peinearydevelopment sorting-list-angular.web.app/library mendekati apa yang ingin saya capai, tetapi saya tidak dapat melihat kode apa pun. Maukah Anda mengarahkan saya ke tempat saya bisa mendapatkannya.   -  person E. Ogony    schedule 04.10.2019
comment
Akan mencoba menambahkan beberapa kode selama akhir pekan   -  person peinearydevelopment    schedule 04.10.2019
comment
@Maihan Nijat Ketika Anda menyebutkan (s.category) tidak ada dalam file JSON saya, saya menyadari bahwa saya mengalami masalah rendering UI karena desain database yang buruk. Saya telah mengedit kode saya untuk memasukkan modelnya, dan meminta apakah Anda dapat melihatnya dan menawarkan panduan. Saya belum menemukan solusi apa pun. Terima kasih.   -  person E. Ogony    schedule 06.10.2019
comment
@Mises Saya menambahkan StackBlitz menunjukkan mengapa tidak disarankan menggunakan pipa untuk ini.   -  person peinearydevelopment    schedule 08.10.2019
comment
@peinearydevelopment Senang mengetahuinya tetapi pipa saya tetap murni dan hanya terpicu pada perubahan sortBy atau filter apa pun. Jadi itu tidak akan merusak pengalaman pengguna.   -  person Mises    schedule 08.10.2019
comment
@Mises Itu benar, tetapi dokumen mengatakan pipa harus tidak murni karena mereferensikan properti objek. Milik Anda tidak memilikinya karena Anda memiliki kode keras di dalam pipa itu sendiri (yaitu title, uploaded). Itu adalah sesuatu yang penting untuk disoroti.   -  person peinearydevelopment    schedule 08.10.2019
comment
@peinearydevelopment Ya saya tahu dan ada opsi untuk membuat kelas menjadi final? Ingin membuatnya tidak bisa diperpanjang?   -  person Mises    schedule 08.10.2019
comment
@peinearydevelopment Karena seseorang dapat memanjangkan pipanya yang tidak murni dengan pipa sortir saya.   -  person Mises    schedule 08.10.2019
comment
@Mises Lihat masalah GitHub   -  person peinearydevelopment    schedule 08.10.2019
comment
@E.Ogony Jika Anda mencoba menerapkan kode di bawah ini dan tidak berhasil, perbarui pertanyaan Anda dengan detailnya. Lebih baik lagi adalah menyediakan StackBlitz Anda sendiri sehingga saya dapat mengatasi perubahan yang Anda perlukan agar semuanya berfungsi.   -  person peinearydevelopment    schedule 08.10.2019
comment
@ peinearydevelopment Saya menghargai perhatian Anda. Silakan temukan tautan ke proyek tersebut. Jika tidak terlalu banyak bertanya, maukah Anda memberikan contoh yang menggunakan layanan untuk mengambil data dari firebase DB. stackblitz.com/edit/angular-99tvpd? semat=1&file=src/aplikasi/   -  person E. Ogony    schedule 11.10.2019


Jawaban (1)


Saya telah membuat StackBlitz dengan kode.

Ada beberapa modifikasi kecil pada html yang Anda berikan di atas. Ada juga tiruan 'firebase' sehingga Anda dapat melihat bahwa saya juga menggunakan data yang Anda berikan di atas. Anda mungkin ingin melihat contoh lengkapnya di sana.

Selain itu, banyak metode yang digunakan di bawah ini berasal dari pembicara luar biasa seperti Deborah Kurata dan lainnya .

Sehubungan dengan pertanyaan Anda tentang pemfilteran,

import { Component } from '@angular/core';
import { FirebaseStub } from './firebase.stub';
import { Observable, BehaviorSubject, Subject } from 'rxjs';
import { mergeMap, map, tap } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  private selectedCategory = new BehaviorSubject<string>('accountingFinance');

  category$: Observable<any>;
  selectedCategory$ = this.selectedCategory.asObservable();
  categories$: Observable<any>;


  constructor(private firebaseStub: FirebaseStub) {
    this.categories$ = this.selectedCategory$
                           .pipe(
                             mergeMap(selectedCategory => this.firebaseStub
                                                              .categories$
                                                              .pipe(map((category: any) => category[selectedCategory]))
                            )
                          );

    this.category$ = firebaseStub.category$
                                 .pipe(
                                   tap((category: any) => this.selectedCategory.next('accountingFinance')),
                                   map(categoryObj => Object.keys(categoryObj).map((key,index) => categoryObj[key].name))
                                  );
  }
}

Saya mencoba mempertahankan konvensi penamaan Anda meskipun agak sulit untuk saya ikuti. Anda akan melihat bahwa categories$ adalah daftar kategori yang difilter berdasarkan daftar lengkap yang diterima dari 'firebase' dan selectedCategory. Secara umum, saya telah melihat nilai SelectCategory berasal dari dropdown di UI, dan ketika pengguna memilih nilai baru, pilihan tersebut akan menjalankan metode untuk memperbarui SelectedCategory (dengan memanggil next di atasnya). Saya telah mengkodekan nilai secara keras di sini lagi, karena ini bukan inti pertanyaan Anda.

Pemfilteran kemudian dilakukan melalui operator rxjs mergeMap. Dibutuhkan nilai terbaru yang dipancarkan oleh selectedCategory$ observable meneruskannya ke operator map yaitu piped melalui categories$ observable Firebase. Kategori terfilter yang dipetakan dikembalikan sebagai categories$ komponen yang dapat diamati.

PEMBARUAN

Sekadar referensi beberapa komentar pada pertanyaan awal. Saya membuat StackBlitz menunjukkan beberapa inefisiensi menggunakan pendekatan pipa tidak murni. Jika Anda membuka Konsol di panel pratinjau, Anda dapat melihat berapa kali pipa tidak murni dipanggil bahkan terkait dengan tindakan yang sama sekali tidak terkait. Setiap kali dipanggil, ui dirender.

person peinearydevelopment    schedule 07.10.2019