【发布时间】:2018-08-07 00:23:39
【问题描述】:
我正在尝试为两级 json 数据实现相同的管道,我在 html 中解析两个嵌套的 ngFor 循环。
home.component.html:
<div class="drop-type">
<div class="label">Multi-select two levels</div>
<div class="search-input-box">
<input [(ngModel)]="searchValue" class="search-input" placeholder="Search...">
<div *ngIf="searchValue && searchValue.length > 1" class="ac-list">
<ul>
<ng-container *ngFor="let value of values | value: searchValue">
<li class="drop-item" (click)="selectMSTLItem(value)">
<div class="check" [ngClass]="{'selected': value.selected}"></div>
<div class="name">{{value.name}}</div>
</li>
<ng-container *ngFor="let subvalue of value.subitems | value: searchValue">
<li class="drop-item sub-item" (click)="selectMSTLItem(subvalue)">
<div class="check" [ngClass]="{'selected': subvalue.selected}"></div>
<div class="name">{{subvalue.name}}</div>
</li>
</ng-container>
</ng-container>
</ul>
</div>
</div>
<ng-container *ngFor="let selectedItem of values">
<div class="selected-drop-item">
<div *ngIf="selectedItem.selected" (click)="deselectMSTLItem(selectedItem)">{{selectedItem.name}}</div>
</div>
<ng-container *ngFor="let selectedSubItem of selectedItem.subitems">
<div class="selected-drop-item">
<div *ngIf="selectedSubItem.selected" (click)="deselectMSTLItem(selectedSubItem)">{{selectedSubItem.name}}</div>
</div>
</ng-container>
</ng-container></div>
home.component.ts:
import { Component, OnInit } from '@angular/core';
import {ValuesService} from './values.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.less']
})
export class HomeComponent implements OnInit {
values: any[] = [];
searchValue: string;
constructor(private valuesService: ValuesService) {
}
ngOnInit() {
this.valuesService.getValues()
.subscribe(
(response) => {
this.values = response.results;
},
(error) => {
console.log(error);
}
);
}
selectMSTLItem(selectedItem) {
selectedItem.selected = !selectedItem.selected;
}
deselectMSTLItem(selectedItem) {
selectedItem.selected = false;
}
}
search.pipe.ts:
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'value'})
export class SearchPipe implements PipeTransform {
transform(values: any, searchValue: any): any {
if (searchValue == null) { return values; }
return values.filter(function(value){
return value.name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1
|| value.subitems.name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
});
}
}
values.service.ts:
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class ValuesService {
private _url = '../assets/values.json';
constructor(private _http: Http) {}
getValues () {
return this._http.get(this._url)
.map((response: Response) => response.json());
}
}
values.json:
{
"results": [
{
"name": "Value 1.0",
"selected": false,
"subitems": [
{
"name": "Value 1.1",
"selected": false
},
{
"name": "Value 1.2",
"selected": false
},
{
"name": "Value 1.3",
"selected": false
}
]
},
{
"name": "Value 2.0",
"subitems": [
{
"name": "Value 2.1",
"selected": false
},
{
"name": "Value 2.2",
"selected": false
},
{
"name": "Value 2.3",
"selected": false
}
]
},
{
"name": "Value 3.0",
"subitems": [
{
"name": "Value 3.1",
"selected": false
},
{
"name": "Value 3.2",
"selected": false
},
{
"name": "Value 3.3",
"selected": false
}
]
}
]
}
我想要完成的是,例如,当用户输入字符串“Va”时,它会列出所有包含字符串“va”的级别 1 和级别 2 名称值,现在它会这样做。但是,当用户想要搜索级别 2 元素并输入字符串“Value 1”时。 (搜索 Value 1.1 或 Value 1.2 等)我收到一个错误
TypeError:无法读取未定义的属性“toLowerCase”
管道中的第二个返回值 (value.subitems.name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1)
我的猜测是,我需要以某种方式在管道中循环遍历所有 2 级元素,并过滤掉那些包含搜索值的元素,然后当然返回这些以及所有 1 级元素。有人可以帮我解决这个问题吗?
【问题讨论】:
标签: angular typescript pipe