[英]Angular How to filter array data by searching in input
How to filter an array object in input text - angular I'm trying to make an search bar to filter where the user can search the location/description which I name it "sensor".如何过滤输入文本中的数组对象 - angular 我正在尝试制作一个搜索栏来过滤用户可以搜索我将其命名为“传感器”的位置/描述的位置。
validateForm: FormGroup;
rowData: templogRecord[] = [];
option: any = [];
onLoad() {
this.rowData = record.default.records;
this.option = [];
this.rowData.forEach(room => {
this.option.push({
tooltip: {
formatter: "{a} <br/>{b} : {c}°"
},
toolbox: {
show: true,
feature: {
mark: { show: false },
restore: { show: false },
saveAsImage: { show: false }
}
},
series: [
{
name: room.sensor,
type: 'gauge',
center: ['40%', '70%'],
splitNumber: 10,
radius: '70%',
axisLine: {
lineStyle: {
color: [[0.2, '#48b'], [0.8, '#228b22'], [1, '#ff0000']],
width: 8
}
},
axisTick: {
splitNumber: 10,
length: 12,
lineStyle: {
color: 'auto'
}
},
axisLabel: {
textStyle: {
color: 'auto'
}
},
splitLine: {
show: true,
length: 30,
lineStyle: {
color: 'auto'
}
},
pointer: {
width: 5
},
title: {
show: true,
offsetCenter: [0, '65%'],
textStyle: {
fontWeight: 'bolder'
}
},
detail: {
formatter: '{value}°',
textStyle: {
color: 'auto',
fontWeight: 'bolder'
}
},
data: [{ value: this.tempGenerator(), name: "Temperature" }]
},
{
name: '转速',
type: 'gauge',
center: ['70%', '25%'],
splitNumber: 10,
radius: '40%',
axisLine: {
lineStyle: {
width: 8
}
},
axisTick: {
length: 12,
lineStyle: {
color: 'auto'
}
},
splitLine: {
length: 20,
lineStyle: {
color: 'auto'
}
},
pointer: {
width: 5
},
title: {
show: true,
offsetCenter: [0, '80%'],
textStyle: {
fontWeight: 'bolder',
}
},
detail: {
formatter: '{value}%',
offsetCenter: [0, '55%'],
textStyle: {
color: 'auto',
fontSize: 18,
fontWeight: 'bolder'
}
},
data: [{ value: 1.5, name: "Humidity" }]
}
]
});
});
}
tempGenerator() {
var time = 12;
var num = Math.random() * 100;
var tempBase = Math.round(num);
var fluc = [0, 1, 1, 2, 1, 1, 2.5, 3.5, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
return tempBase * fluc[time];
}
searchData(searchValue: any) {
if (searchValue.length >= 3) {
this.rowData = this.rowData.filter((data: templogRecord) => {
console.log(data['sensor']);
});
} else if (searchValue.length < 1) {
console.log('empty')
}
}
}
{
"records": [
{
"dateandtime": "2018-06-14 02:24:02",
"sensor": "Nine Seal Area",
"temperature": "25.9",
"humidity": "99.9"
},
{
"dateandtime": "2018-06-14 02:24:02",
"sensor": "Ten Line2",
"temperature": "25.9",
"humidity": "99.9"
},
{
"dateandtime": "2018-06-14 02:22:01",
"sensor": "Eight Line1",
"temperature": "25.9",
"humidity": "99.9"
}
]
}
room-list.component.html房间列表.component.html
<div class="flex-container">
<div class="date-filter">
<nz-input-group [nzSuffix]="suffixIconSearch">
<input type="text"
nz-input placeholder="Search"
[(ngModel)]="filterSearch"
(ngModelChange)="searchData($event)"
/>
</nz-input-group>
<ng-template #suffixIconSearch>
<i nz-icon nzType="search"></i>
</ng-template>
</div>
<ul class="cards">
<li class="cards__item" *ngFor="let data of option">
<div class="card">
<div echarts [options]="data" [autoResize]="true"></div>
<div class="card__content">
<button class="btn btn--block card__btn">Button</button>
</div>
</div>
</li>
</ul>
</div>
In the searchData
function, I'm trying to make it filtering while typing based in location/description which I named it "sensor".在
searchData
函数中,我试图在根据我将其命名为“传感器”的位置/描述进行键入时对其进行过滤。
Each time you make a search, you're filtering the elements in your array and giving the output to your original array.每次进行搜索时,都会过滤数组中的元素并将输出提供给原始数组。 Consequently, you loose your data.
因此,您会丢失数据。 Why don't you create 2 variables:
为什么不创建 2 个变量:
searchData(searchValue: any) {
this.filteredData = this.rowData.filter((item: templogRecord) => {
return item.sensor.toLowerCase().includes(searchValue.toLowerCase());
});
}
I would recommend this solution (Based on materials autocomplete: https://stackblitz.com/angular/lndebkoyare?file=app%2Fautocomplete-filter-example.ts )我会推荐这个解决方案(基于材料自动完成: https : //stackblitz.com/angular/lndebkoyare? file = app%2Fautocomplete-filter- example.ts )
In your component:在您的组件中:
import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
/**
* @title Filter autocomplete
*/
@Component({
selector: 'autocomplete-filter-example',
templateUrl: 'autocomplete-filter-example.html',
styleUrls: ['autocomplete-filter-example.css'],
})
export class FilterExample implements OnInit {
// your control for input
searchControl = new FormControl();
// your whole set of options
options: string[] = ['One', 'Two', 'Three'];
// your current result based on filters input
filteredOptions: Observable<string[]>;
ngOnInit() {
this.filteredOptions = this.searchControl.valueChanges
.pipe(
startWith(''),
map(value => this._filter(value))
);
}
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.toLowerCase().includes(filterValue));
}
}
Your template would look like this:您的模板如下所示:
<div class="flex-container">
<div class="date-filter">
<nz-input-group [nzSuffix]="suffixIconSearch">
<input type="text"
nz-input placeholder="Search"
[formControl]="searchControl"
/>
</nz-input-group>
<ng-template #suffixIconSearch>
<i nz-icon nzType="search"></i>
</ng-template>
</div>
<ul class="cards">
<li class="cards__item" *ngFor="let data of filteredOptions | async">
<div class="card">
<div echarts [options]="data" [autoResize]="true"></div>
<div class="card__content">
<button class="btn btn--block card__btn">Button</button>
</div>
</div>
</li>
</ul>
Every time value on input changes the observable valueChanges
on searchControl
emits the current value of this input field.每次输入上的值更改
searchControl
上的可观察valueChanges
, searchControl
发出此输入字段的当前值。 This part map(value => this._filter(value))
returns a filtered subset of your options array.这部分
map(value => this._filter(value))
返回选项数组的过滤子集。 Which can be displayd using the async pipe: <li class="cards__item" *ngFor="let data of filteredOptions | async">...</li>
可以使用异步管道显示:
<li class="cards__item" *ngFor="let data of filteredOptions | async">...</li>
DO NOT USE find
or includes
, because these are not supported by the Internet Explorer.不要使用
find
或includes
,因为 Internet Explorer 不支持这些。
How about using javascript's filter
function?使用javascript的
filter
功能怎么样? See an example below.请参阅下面的示例。
The following example assumes that you are targeting the sensor
element in the object.下面的示例假设您以对象中的
sensor
元素为目标。
const test = {
"records": [
{
"dateandtime": "2018-06-14 02:24:02",
"sensor": "Nine Seal Area",
"temperature": "25.9",
"humidity": "99.9"
},
{
"dateandtime": "2018-06-14 02:24:02",
"sensor": "Ten Line2",
"temperature": "25.9",
"humidity": "99.9"
},
{
"dateandtime": "2018-06-14 02:22:01",
"sensor": "Eight Line1",
"temperature": "25.9",
"humidity": "99.9"
}
]
};
let found = [];
const searchTerm = 'Eight Line1';
found = test.records.filter(function(element) {
return element.sensor.toLowerCase() == searchTerm.toLowerCase();
});
console.log('found ' , found[0]);
Update更新
To perform a partial search (searching for a part of the string), you can safely use indexOf
.要执行部分搜索(搜索字符串的一部分),您可以安全地使用
indexOf
。 See an example below,看下面的例子,
console.log("Eight Line1".indexOf("Ei") !== -1);
Hope this helps,希望这可以帮助,
Thanks.谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.