Bagaimana cara memfilter array dengan TypeScript di Angular 2?

109

ng-2 pewarisan data orang tua-anak telah menjadi kesulitan bagi saya.

Apa yang tampaknya bisa menjadi solusi praktis yang berfungsi dengan baik adalah memfilter total array data saya ke array yang hanya terdiri dari data anak yang direferensikan oleh id orang tua tunggal. Dengan kata lain: data-inheritance menjadi pemfilteran data oleh satu id induk.

Dalam contoh konkret ini dapat terlihat seperti: memfilter larik buku untuk hanya menampilkan buku dengan yang tertentu store_id.

import {Component, Input} from 'angular2/core';

export class Store {
  id: number;
  name: string;
}

export class Book {
  id: number;
  shop_id: number;
  title: string;
}

@Component({
  selector: 'book',
  template:`
    <p>These books should have a label of the shop: {{shop.id}}:</p>

    <p *ngFor="#book of booksByShopID">{{book.title}}</p>
  `
])
export class BookComponent {
  @Input()
  store: Store;

  public books = BOOKS;

  // "Error: books is not defined"
  // ( also doesn't work when books.filter is called like: this.books.filter
  // "Error: Cannot read property 'filter' of undefined" )
  var booksByStoreID = books.filter(book => book.store_id === this.store.id)
}

var BOOKS: Book[] = [
  { 'id': 1, 'store_id': 1, 'name': 'Dichtertje' },
  { 'id': 2, 'store_id': 1, 'name': 'De uitvreter' },
  { 'id': 3, 'store_id': 2, 'name': 'Titaantjes' }
];

TypeScript baru bagi saya, tetapi saya pikir saya hampir membuat semuanya berfungsi di sini.

(Juga menimpa larik buku asli bisa menjadi opsi, lalu menggunakan *ngFor="#book of books".)

EDIT Semakin dekat, namun tetap memberikan error.

//changes on top:
import {Component, Input, OnInit} from 'angular2/core';

// ..omitted

//changed component:
export class BookComponent implements OnInit {
  @Input() 
  store: Store;

  public books = BOOKS;

  // adding the data in a constructor needed for ngInit
  // "EXCEPTION: No provider for Array!"
  constructor(
    booksByStoreID: Book[];
  ) {}


  ngOnInit() {
    this.booksByStoreID = this.books.filter(
      book => book.store_id === this.store.id);
  }
}

// ..omitted
Code-MonKy
sumber

Jawaban:

205

Anda perlu memasukkan kode Anda ngOnInitdan menggunakan thiskata kunci:

ngOnInit() {
  this.booksByStoreID = this.books.filter(
          book => book.store_id === this.store.id);
}

Anda perlu ngOnInitkarena input storetidak akan disetel ke konstruktor:

ngOnInit dipanggil tepat setelah properti terikat data direktif diperiksa untuk pertama kalinya, dan sebelum anak-anaknya diperiksa. Itu dipanggil hanya sekali ketika direktif dibuat.

( https://angular.io/docs/ts/latest/api/core/index/OnInit-interface.html )

Dalam kode Anda, pemfilteran buku secara langsung ditentukan ke dalam konten kelas ...

Thierry Templier
sumber
Masuk akal. Saya mendapatkan pesan kesalahan "Kesalahan: ngOnInit tidak ditentukan" setelah menambahkan bagian kode Anda, mengimpor OnInitdan menambahkan booksByStoreID = Book[];komponen.
Code-MonKy
Saya pikir itu lebih tepatnya:booksByStoreID: Book[];
Thierry Templier
Juga tidak berhasil. Haruskah saya meletakkan ini di konstruktor? Saya mencoba ini, kemudian saya mendapatkan kesalahan mengeluh tentang]
Code-MonKy
1
Terima kasih! Pemfilteran berhasil sepenuhnya :) Namun, masalah baru muncul. Saat mengklik di komponen induk sehingga toko lain dipilih, store_id lama tetap ada dan daftar buku tetap sama ...
Code-MonKy
1
Luar biasa. selamat atas 200 suara !!!
Amuk Saxena
18

Anda dapat memeriksa contoh di Plunker di sini contoh filter plunker

filter() {

    let storeId = 1;
    this.bookFilteredList = this.bookList
                                .filter((book: Book) => book.storeId === storeId);
    this.bookList = this.bookFilteredList; 
}
yaircarreno
sumber
4

Untuk memfilter larik terlepas dari jenis properti (yaitu untuk semua jenis properti), kita dapat membuat pipa filter kustom

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: "filter" })
export class ManualFilterPipe implements PipeTransform {
  transform(itemList: any, searchKeyword: string) {
    if (!itemList)
      return [];
    if (!searchKeyword)
      return itemList;
    let filteredList = [];
    if (itemList.length > 0) {
      searchKeyword = searchKeyword.toLowerCase();
      itemList.forEach(item => {
        //Object.values(item) => gives the list of all the property values of the 'item' object
        let propValueList = Object.values(item);
        for(let i=0;i<propValueList.length;i++)
        {
          if (propValueList[i]) {
            if (propValueList[i].toString().toLowerCase().indexOf(searchKeyword) > -1)
            {
              filteredList.push(item);
              break;
            }
          }
        }
      });
    }
    return filteredList;
  }
}

//Usage

//<tr *ngFor="let company of companyList | filter: searchKeyword"></tr>

Jangan lupa untuk mengimpor pipa di modul aplikasi

Kita mungkin perlu menyesuaikan logika ke filer dengan tanggal.

alchi baucha
sumber