Javascript Knockoutjs arrayFilter多个下拉列表

Javascript Knockoutjs arrayFilter多个下拉列表,javascript,knockout.js,Javascript,Knockout.js,我有一个关于knockoutjs中arrayFilter的问题,我将如何使用两个不同的下拉列表过滤我的列表,这两个下拉列表将相互关联,因此如果我选择了1种类型的建筑,但没有区域,我应该显示所有类型的建筑,然而,如果我在哪里选择一个建筑选项和一个面积选项,过滤应该考虑到这一点,我已经在一个原型上工作了两天,但是我不知道如何在arrayfilter中返回正确的项目 目前,我通过viewmodel制作了所有的模型和粘贴数据,并连接了一个过滤列表,但是我不知道如何通过foreach过滤器和arrayF

我有一个关于knockoutjs中arrayFilter的问题,我将如何使用两个不同的下拉列表过滤我的列表,这两个下拉列表将相互关联,因此如果我选择了1种类型的建筑,但没有区域,我应该显示所有类型的建筑,然而,如果我在哪里选择一个建筑选项和一个面积选项,过滤应该考虑到这一点,我已经在一个原型上工作了两天,但是我不知道如何在arrayfilter中返回正确的项目

目前,我通过viewmodel制作了所有的模型和粘贴数据,并连接了一个过滤列表,但是我不知道如何通过foreach过滤器和arrayFilter返回正确的项目,这就是它变得有点模糊的地方

       self.filteredList = ko.computed(function () {
            var filters = [];
            filters.push(self.selectedBuilding());
            filters.push(self.selectedArea());
           var currentList = [];

            ko.utils.arrayForEach(filters, function (filter) {
                if (typeof filter !== "undefined") {
                 ko.utils.arrayFilter(self.products(), function (item) {
                    if (filter.id == item.areaId || filter.value == item.buildingId) {
                            currentList.push(item);
                        } 
                 });
                }

            });
            return currentList;
        });
提前感谢您的回答

您有两个问题:

  • 您没有正确使用
    ko.utils.arrayFilter
    :您必须返回
    true
    false
    ,这取决于最终结果中是否应包含和项。因此,您不应该在
    arrayFilter
  • 您总是从完整列表开始,不一个接一个地应用过滤器,但在
    arrayFilter
    中错误地生成结果,这导致您的过滤器与或不与和(如您最初所需)组合
您的固定代码如下所示:

self.filteredList = ko.computed(function () {
    var filters = [];
    filters.push(self.selectedBuilding());
    filters.push(self.selectedArea());
    var currentList = self.products();

    ko.utils.arrayForEach(filters, function (filter) {
        if (typeof filter !== "undefined") {
            currentList = ko.utils.arrayFilter(currentList, function (item) {
                if (filter.id == item.areaId || filter.value == item.buildingId) {
                    return true;
                }
            });
        }
    });
    return currentList;
});
演示

两个更好的方法查看过滤。使用相同的列表,您可以重写代码,分两个单独的步骤进行过滤:

self.filteredList = ko.computed(function () {
    var currentList = self.products();
    if (self.selectedBuilding())
    {
        currentList = ko.utils.arrayFilter(currentList, function(item) {
            return self.selectedBuilding().value == item.buildingId;
        });
    }
    if (self.selectedArea())
    {
        currentList = ko.utils.arrayFilter(currentList, function(item) {
            return self.selectedArea().id == item.areaId;
        });
    }
    return currentList;
});
在这段代码中,从完整列表开始,然后逐个应用不同的过滤器,对原始列表进行越来越深入的过滤,这一点更加清楚

演示

注意:如果最初希望以空列表开始(如原始代码中),那么如果所有筛选器都为空,则可以返回空数组:

self.filteredList = ko.computed(function () {
    if (!self.selectedBuilding() && !self.selectedArea())
        return [];
    //...
};
演示。

您有两个问题:

  • 您没有正确使用
    ko.utils.arrayFilter
    :您必须返回
    true
    false
    ,这取决于最终结果中是否应包含和项。因此,您不应该在
    arrayFilter
  • 您总是从完整列表开始,不一个接一个地应用过滤器,但在
    arrayFilter
    中错误地生成结果,这导致您的过滤器与或不与和(如您最初所需)组合
您的固定代码如下所示:

self.filteredList = ko.computed(function () {
    var filters = [];
    filters.push(self.selectedBuilding());
    filters.push(self.selectedArea());
    var currentList = self.products();

    ko.utils.arrayForEach(filters, function (filter) {
        if (typeof filter !== "undefined") {
            currentList = ko.utils.arrayFilter(currentList, function (item) {
                if (filter.id == item.areaId || filter.value == item.buildingId) {
                    return true;
                }
            });
        }
    });
    return currentList;
});
演示

两个更好的方法查看过滤。使用相同的列表,您可以重写代码,分两个单独的步骤进行过滤:

self.filteredList = ko.computed(function () {
    var currentList = self.products();
    if (self.selectedBuilding())
    {
        currentList = ko.utils.arrayFilter(currentList, function(item) {
            return self.selectedBuilding().value == item.buildingId;
        });
    }
    if (self.selectedArea())
    {
        currentList = ko.utils.arrayFilter(currentList, function(item) {
            return self.selectedArea().id == item.areaId;
        });
    }
    return currentList;
});
在这段代码中,从完整列表开始,然后逐个应用不同的过滤器,对原始列表进行越来越深入的过滤,这一点更加清楚

演示

注意:如果最初希望以空列表开始(如原始代码中),那么如果所有筛选器都为空,则可以返回空数组:

self.filteredList = ko.computed(function () {
    if (!self.selectedBuilding() && !self.selectedArea())
        return [];
    //...
};

演示。

非常感谢!我研究这个问题已经有一段时间了,只是不能正确地进行过滤,我开始了整个foreach过滤器,这让我非常困惑,这个解决方案清晰易读,非常好。我会将此标记为答案。我最终使用了最后一个选项,因为这比我最初的代码要干净得多,这对我了解如何更有效地编写此代码非常有帮助,是否可以对下拉列表进行类似的筛选,以便在没有内容的情况下不在列表中显示它们,我试着在这里用小提琴演奏。感谢您所花的时间@JakobKristensen强烈建议,如果你有这些不同但后续的问题,你可以单独提问。在评论中很难正确回答,其他用户可能不会注意到并在评论中隐藏问题。另一方面,你的描述不是很清楚,我不知道你是如何想象下拉列表的过滤的。。。你在找这样的问题吗:?这正是我想要的解决方案,下次我会提出一个后续问题,谢谢你的澄清。我的尝试看起来有点不同,我喜欢你的方法,但是,非常感谢你在这些问题上的帮助。非常感谢!我研究这个问题已经有一段时间了,只是不能正确地进行过滤,我开始了整个foreach过滤器,这让我非常困惑,这个解决方案清晰易读,非常好。我会将此标记为答案。我最终使用了最后一个选项,因为这比我最初的代码要干净得多,这对我了解如何更有效地编写此代码非常有帮助,是否可以对下拉列表进行类似的筛选,以便在没有内容的情况下不在列表中显示它们,我试着在这里用小提琴演奏。感谢您所花的时间@JakobKristensen强烈建议,如果你有这些不同但后续的问题,你可以单独提问。在评论中很难正确回答,其他用户可能不会注意到并在评论中隐藏问题。另一方面,你的描述不是很清楚,我不知道你是如何想象下拉列表的过滤的。。。你在找这样的问题吗:?这正是我想要的解决方案,下次我会提出一个后续问题,谢谢你的澄清。我的尝试看起来有点不同,我喜欢你的方法,但是,非常感谢你在这些问题上的帮助。