【问题标题】:AngularJS dynamic list of filtersAngularJS 动态过滤器列表
【发布时间】:2014-06-09 18:56:49
【问题描述】:

我有一份产品清单。每个产品都有三个属性:mustBuy、promotion(都是布尔值)和productName。我要做的是根据用户输入一次应用一个过滤器。如果用户单击一个名为“必须购买”的按钮,产品将被 mustBuy 字段过滤,因此一旦我单击该按钮,我应该只会看到 mustBuy 属性值为 true 的产品。 我想以动态方式生成这些过滤器按钮,因为稍后我可能会添加额外的属性。现在我有一个用于过滤的硬编码按钮列表:

        <a ng-click="myFilter = {mustBuy:true}">
            <img src="/images/must-filter.png" />
        </a>
        <a ng-click="myFilter = {promotion:true}">
            <img src="/images/promo-filter.png" />
        </a>

这是“myFilter”过滤的内容。

<div ng-repeat="product in products | filter:myFilter">...</div>

它工作正常,但我想让这些过滤器动态化,因为我会在未来添加更多。这是我尝试过的: (v1): Js控制器:

        $scope.filters = [{ image: "must-filter.png", myFilter: { mustBuy: true } }, { image: "promo-filter.png", myFilter: { promotion: true } }];

HTML:

        <a ng-repeat="f in filters | filter:f.myFilter">
            <img src="/images/{{f.image}}" />
        </a>

(v2): Js控制器:

        $scope.filters = [{ image: "must-filter.png", myFilter: { mustBuy:true } }, { image: "promo-filter.png",  myFilter: {promotion:true} }];

HTML:

        <a ng-repeat="f in filters"
           ng-click="{{f.myFilter}}">
            <img src="/images/{{f.image}}" />
        </a>

(v3):

Js 控制器:

       $scope.filters = [{ image: "must-filter.png", myFilter: "myFilter = {mustBuy:true}" }, { image: "promo-filter.png",  myFilter: "myFilter = {promotion:true}" }];

HTML:

        <a ng-repeat="f in filters"
           ng-click="{{f.myFilter}}">
            <img src="/images/{{f.image}}" />
        </a>

第三种方法 (v3) 具有与原始(硬编码)方法完全相同的 HTML 输出,只是它不起作用,这让我认为幕后发生了更多(绑定)事情?如何实现第一段中描述的功能?

【问题讨论】:

  • 是的,有……现在,问题来了?
  • 我改写了这个问题以使其更清楚。谢谢。

标签: javascript angularjs angularjs-ng-repeat angularjs-filter


【解决方案1】:

不用看太多(完全)你的尝试失败的原因,你可以像这样实现你想要的:

1.)
在控制器中定义过滤器列表和当前选择(应用)的过滤器:

$scope.filters = [
    {name: 'none',      filterExpr: ''},
    {name: 'must buy',  filterExpr: {mustBuy: true}},
    {name: 'promotion', filterExpr: {promotion: true}}
];
$scope.selectedFilter = $scope.filters[0];

(我的过滤器对象有一个name 和一个filterExpr,但您可以根据需要调整它们。)


2.)
定义一个用于更改应用过滤器的函数(当然也是在控制器中):

$scope.setFilter = function (filter) {
    $scope.selectedFilter = filter;
};

3.)
让用户更改应用的过滤器(在视图中):

<ul>
    <li ng-repeat="filter in filters">
        <a href="" ng-click="setFilter(filter)">{{filter.name}}</a>
    </li>
</ul>

4.)
根据当前选择的过滤器的过滤器表达式过滤项目:

<ul>
    <li ng-repeat="item in items | filter:selectedFilter.filterExpr">
        {{item.description}}
    </li>
</ul>

另请参阅此short demo

【讨论】:

  • 谢谢!所以我毕竟不得不使用一个函数。顺便说一句,非常简单优雅的解决方案。
【解决方案2】:

正如您在此 FIDDLE 中所见,您必须使用函数或自定义过滤器来链接您的动态过滤器。

过滤器集:

//this set will filter everything but true-false
$scope.set1 = [function(item){return item.mustBuy;},
               function(item){return !item.promotion}];

过滤功能:

$scope.multipleFilters = function(item){
    var v = true;
    for(var i=0; i<$scope.set1.length; i++){
        v = v && $scope.set1[i](item);
    }
    return v;
};

这样使用:

<div ng-repeat="product in products | filter:multipleFilters">
    {{product.mustBuy}} - {{product.promotion}}
</div>

重点是使用像 function(item){return item.mustBuy} 这样的过滤器的函数,而不是像 {mustBuy:true} 这样的表达式

【讨论】:

  • 感谢您的回答!我认为我没有正确表达自己,我将修改原始问题以使其更清楚。我要做的是根据用户输入一次应用一个过滤器。如果用户点击一个名为“必须购买”的按钮,产品将被 mustBuy 字段过滤。所以我只会看到 mustBuy 属性值为 true 的产品。在尝试简化示例和代码示例时,我省略了其他字段(例如产品名称、产品图像等)。
猜你喜欢
  • 2014-07-31
  • 1970-01-01
  • 2016-12-06
  • 2017-06-08
  • 1970-01-01
  • 2023-03-03
  • 2014-07-29
  • 2014-12-11
  • 1970-01-01
相关资源
最近更新 更多