0

我在 AngularJS 中有一个基本应用程序。该模型包含许多项目和这些项目的相关标签。我想要实现的是过滤显示的项目的能力,以便只显示那些具有一个或多个活动标签的项目,但是我在弄清楚如何从视图中操作模型方面运气不佳。

JS 可在http://jsfiddle.net/Qxbka/2获得。这包含到目前为止我设法达到的状态,但我有两个问题。首先,该指令尝试调用toggleTag()控制器中的方法:

template: "<button class='btn' ng-repeat='datum in data' ng-click='toggleTag(datum.id)'>{{datum.name}}</button>"

但没有调用该方法。其次,我不确定如何更改输出部分ng-repeat,使其仅显示具有一个或多个活动标签的项目。

任何关于我做错了什么以及如何使它工作的指针都将不胜感激。

更新 我更新了指令中的方法直接传递数据项,即

template: "<button class='btn' ng-repeat='datum in data' ng-click='toggle(data, datum.id)'>{{datum.name}}</button>"

并且还在toggle()指令中创建了一个方法。通过这样做,我可以进行操作data,它会反映在状态 HTML 中,但是如果这是否是正确的方法,我将不胜感激(我感觉不太正确)。

仍然坚持如何在更新标签值时重新评估输出。

4

1 回答 1

0

您可以在以下位置使用过滤器(文档ng-repeat

<li ng-repeat="item in items | filter:tagfilter">...</li>

过滤器表达式的参数可以是很多东西,包括作用域上的一个函数,它将为数组中的每个元素调用一次。如果返回 true,则元素会显示,如果返回 false,则不会。

你可以这样做的一种方法是在你的范围内设置一个selectedTags数组,你可以通过观察tags数组来填充它:

$scope.$watch('tags', function() {
    $scope.selectedTags = $scope.tags.reduce(function(selected, tag) {
        if (tag._active) selected.push(tag.name);
        return selected;
    }, []);
}, true);

最后的额外true内容使角度通过相等与引用比较元素(这是我们想要的,因为我们需要它来观察_active每个标签上的属性。

接下来可以设置过滤功能:

$scope.tagfilter = function(item) {
    // If no tags are selected, show all the items.
    if ($scope.selectedTags.length === 0) return true;

    return intersects($scope.selectedTags, item.tags);
}

使用返回两个数组的交集的快速而肮脏的辅助函数intersects

function intersects(a, b) {
    var i = 0, len = a.length, inboth = [];

    for (i; i < len; i++) {
        if (b.indexOf(a[i]) !== -1) inboth.push(a[i]);
    }

    return inboth.length > 0;
}

在这里叉了你的小提琴来展示这一点。

One small issue with the way you've gone about this is items have an array of tag "names" and not ids. So this example just works with arrays of tag names (I had to edit some of the initial data to make it consistent).

于 2013-02-15T17:26:13.913 回答