Próbowałem zbudować proste filtrowanie w aplikacji -> Show-ur-bugs (https://github.com/fedojo/show-ur-bugs).
Pozwólcie, że najpierw przedstawię środowisko błędu:
project-list.component.ts
import 'rxjs/add/operator/map';
import {Component, OnInit} from '@angular/core';
import {ProjectService} from "../../shared";
import {ProjectListSingleComponent} from "./project/project-list-single.component";
import {FilterData} from "../../filter-data.pipe";
@Component({
moduleId: module.id,
bindings: [ProjectService],
selector: 'app-project-list',
templateUrl: 'project-list.component.html',
styleUrls: ['project-list.component.css'],
directives: [ProjectListSingleComponent],
pipes: [FilterData]
})
export class ProjectListComponent implements OnInit {
projects;
constructor(public projectService:ProjectService) {
}
getProjects() {
this.projectService.getProjects()
.subscribe(
data => {
this.projects = data;
},
error => console.error('Error: ' + error[0]),
() => {}
)
}
ngOnInit() {
this.getProjects();
}
}
project-list.component.html
<input type="text" #filter (keyup)="0">
<project-list-single *ngFor="let project of (projects | filterData: filter.value)"
[project]="project"
class="project"></project-list-single>
filter-data.pipe.ts - wer 1
import {Pipe, PipeTransform} from '@angular/core';
import {ProjectItem} from './projects/index';
@Pipe({
name: 'filterData'
})
export class FilterData implements PipeTransform {
transform(value:ProjectItem[], args:string[]):any {
if (value.length === 0) {
return value;
}
var resultArray = [];
for (let item of value) {
if (item.name.match('^.*' + args[0] + '.*$')) {
resultArray.push(item);
}
}
return resultArray;
}
}
Wystąpił błąd:
ORIGINAL EXCEPTION: TypeError: Cannot read property 'length' of undefined
Ale który element nie ma length? Po szybkim zbadaniu kodu okazało się, że obiekt przekazany do Pipe nie istniał w momencie wywołania Pipe. Więc oto pomysł na rozwiązanie:
filter-data.pipe.ts - wer 2
import {Pipe, PipeTransform} from '@angular/core';
import {ProjectItem} from './projects/index';
@Pipe({
name: 'filterData'
})
export class FilterData implements PipeTransform {
transform(value:ProjectItem[], args:string[]):any {
if (typeof value === 'object') {
var resultArray = [];
if (args.length === 0) {
for (let item of value) {
resultArray.push(item);
}
}
else {
for (let item of value) {
if (item.name.match('^.*' + args[0] + '.*$')) {
resultArray.push(item);
}
}
}
return resultArray;
}
}
}
Dlaczego potrzebujesz tego warunku w pipe?
if (args.length === 0) {
for (let item of value) {
resultArray.push(item);
}
}
Gdy twoja tablica obiektów zostanie załadowana, zostanie automatycznie przekazana do Pipe, który sprawdza wartość z twojego inputa. Gdy input jest pusty, wynik Pipe również będzie pusty, więc nie zobaczysz swoich obiektów na liście.






