如何使用 AngularJS 过滤 JSON 数据?
How to filter the JSON data using AngularJS?
我有三个 dropdown
箱子。我需要过滤数据并需要根据我的复选框 selection(使用 single checkbox
或 two checkboxes
或 three checkboxes
)显示在 table 中。
我做了以下操作,但如果我们观察清楚,我无法使用AngularJS
正确过滤数据。
喜欢:
一个。它应该适用于 individual checkbox selection
:意味着如果我 select 来自 Name
或 Description
或 Field4
的任何 single checkbox
,则相应的匹配过滤数据应该显示在 table 中,否则它不应该显示任何数据(即如果它不匹配我们的复选框 selection 意味着它不会显示任何数据)
b。它应该适用于 multiple(two) checkbox selection
:意味着如果我 select 任何多个复选框,例如 one from Name
和 one from Description
or
one from Description
和 one from Field4
or
one from Field4
和 one from Name
,则相应的过滤数据应该显示在 table 中,否则不应显示任何数据(即如果不匹配我们的复选框 selection 意味着它不会显示任何数据)
c。它应该适用于 multiple(three) checkbox selection
:意味着如果我 select 三个复选框,如 one from Name
和 one from Description
和 one from Field4
,那么相应的匹配过滤数据应该显示在table,否则它不应该显示任何数据(即如果它不匹配我们的复选框 selection 意味着它不会显示任何数据)
第一次正常工作 checkbox
selection only, means: 在加载上述 code/app 之后,如果我们 check
在 selection 以上(比如 single checkbox
selection 或 two checkbox
selection 或 three checkbox
selection)然后它工作正常,后来它不起作用(意味着如果我们 uncheck
上面的任何标准,然后如果我们 select 任何 checkbox
再次那么它不起作用,为此我们需要再次刷新 app/code 那么只有它在工作)。
示例:如果我select一个来自Name,那么相应的匹配数据将被显示。然后再一次,如果我 uncheck
和 check
和 Description
一样的 some other checkbox
那么它就不起作用了。同样适用于所有上述标准。你可以observe
清楚。
请让我知道我在这里做错了什么,让我知道如何正确过滤它。创建 Fiddle。提前致谢!
问题出在复杂的过滤逻辑上。每当您发现自己嵌套了很多 if
语句时,请考虑重新组织分支逻辑。通过将其分解成更小的组件,您可以使其更易于管理,如果您可以完全避免使用 if
,那么您只需测试一条路径,而不是几条路径。
每次用户选中一个框时,我们都需要确保只显示匹配的项目,无论选中多少个框。所以我们需要知道 1) 有多少个框被选中,n,以及 2) 有多少项目可以通过 n 匹配字段找到。
我们可以利用布尔变量可以转换为整数(0 = false,true = 1)这一事实,并使用它来计算选中框的数量以及找到的匹配项的数量。
我们也可以将字段名放入一个数组中,这样我们的函数中就不会有太多的重复。
var fields = ["name", "description", "field4"];
//for each field, count how many fields the item matches
function getMatches(item, matchesNeeded) {
var foundMatches = 0;
fields.forEach(field => {
foundMatches += item[field] === $scope.pagedItems[field]
});
//make sure found at least one match and found desired minimum
return foundMatches && foundMatches >= matchesNeeded;
}
//count how many boxes are checked
//this will tell us how many different fields we are matching on
function numChecked() {
var count = 0;
fields.forEach(field => {
//this will auto convert falsy to 0.
//truthy values will be 1
count += Boolean($scope.pagedItems[field]);
});
return count;
}
$scope.filterItems = function(item) {
return getMatches(item, numChecked());
};
正如@Larry 指出的那样,它更多地基于逻辑。为此,我修改了 Apress 的书 'Pro AngularJS' Source Code from GIT。
过滤函数中的基本逻辑如下-
$scope.categoryFilterFn = function (product) {
var canHave = false;//dont load by default
var atLeastOneTrue = false;//Check if previously checked any condition
angular.forEach(filterValues, function(selectedValue, key) {
var selectVals = Object.values(selectedValue);
if(selectVals.indexOf(product[key]) !== -1) {//if values exits in product.
canHave = !atLeastOneTrue ? true : canHave;
}else{
canHave = false;
}
atLeastOneTrue = true;
});
return canHave;
}
我有三个 dropdown
箱子。我需要过滤数据并需要根据我的复选框 selection(使用 single checkbox
或 two checkboxes
或 three checkboxes
)显示在 table 中。
我做了以下操作,但如果我们观察清楚,我无法使用AngularJS
正确过滤数据。
喜欢:
一个。它应该适用于 individual checkbox selection
:意味着如果我 select 来自 Name
或 Description
或 Field4
的任何 single checkbox
,则相应的匹配过滤数据应该显示在 table 中,否则它不应该显示任何数据(即如果它不匹配我们的复选框 selection 意味着它不会显示任何数据)
b。它应该适用于 multiple(two) checkbox selection
:意味着如果我 select 任何多个复选框,例如 one from Name
和 one from Description
or
one from Description
和 one from Field4
or
one from Field4
和 one from Name
,则相应的过滤数据应该显示在 table 中,否则不应显示任何数据(即如果不匹配我们的复选框 selection 意味着它不会显示任何数据)
c。它应该适用于 multiple(three) checkbox selection
:意味着如果我 select 三个复选框,如 one from Name
和 one from Description
和 one from Field4
,那么相应的匹配过滤数据应该显示在table,否则它不应该显示任何数据(即如果它不匹配我们的复选框 selection 意味着它不会显示任何数据)
第一次正常工作 checkbox
selection only, means: 在加载上述 code/app 之后,如果我们 check
在 selection 以上(比如 single checkbox
selection 或 two checkbox
selection 或 three checkbox
selection)然后它工作正常,后来它不起作用(意味着如果我们 uncheck
上面的任何标准,然后如果我们 select 任何 checkbox
再次那么它不起作用,为此我们需要再次刷新 app/code 那么只有它在工作)。
示例:如果我select一个来自Name,那么相应的匹配数据将被显示。然后再一次,如果我 uncheck
和 check
和 Description
一样的 some other checkbox
那么它就不起作用了。同样适用于所有上述标准。你可以observe
清楚。
请让我知道我在这里做错了什么,让我知道如何正确过滤它。创建 Fiddle。提前致谢!
问题出在复杂的过滤逻辑上。每当您发现自己嵌套了很多 if
语句时,请考虑重新组织分支逻辑。通过将其分解成更小的组件,您可以使其更易于管理,如果您可以完全避免使用 if
,那么您只需测试一条路径,而不是几条路径。
每次用户选中一个框时,我们都需要确保只显示匹配的项目,无论选中多少个框。所以我们需要知道 1) 有多少个框被选中,n,以及 2) 有多少项目可以通过 n 匹配字段找到。
我们可以利用布尔变量可以转换为整数(0 = false,true = 1)这一事实,并使用它来计算选中框的数量以及找到的匹配项的数量。
我们也可以将字段名放入一个数组中,这样我们的函数中就不会有太多的重复。
var fields = ["name", "description", "field4"];
//for each field, count how many fields the item matches
function getMatches(item, matchesNeeded) {
var foundMatches = 0;
fields.forEach(field => {
foundMatches += item[field] === $scope.pagedItems[field]
});
//make sure found at least one match and found desired minimum
return foundMatches && foundMatches >= matchesNeeded;
}
//count how many boxes are checked
//this will tell us how many different fields we are matching on
function numChecked() {
var count = 0;
fields.forEach(field => {
//this will auto convert falsy to 0.
//truthy values will be 1
count += Boolean($scope.pagedItems[field]);
});
return count;
}
$scope.filterItems = function(item) {
return getMatches(item, numChecked());
};
正如@Larry 指出的那样,它更多地基于逻辑。为此,我修改了 Apress 的书 'Pro AngularJS' Source Code from GIT。
过滤函数中的基本逻辑如下-
$scope.categoryFilterFn = function (product) {
var canHave = false;//dont load by default
var atLeastOneTrue = false;//Check if previously checked any condition
angular.forEach(filterValues, function(selectedValue, key) {
var selectVals = Object.values(selectedValue);
if(selectVals.indexOf(product[key]) !== -1) {//if values exits in product.
canHave = !atLeastOneTrue ? true : canHave;
}else{
canHave = false;
}
atLeastOneTrue = true;
});
return canHave;
}