我在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>"
并在指令中创建了CCD_ 3方法。通过这样做,我可以操作data
,它反映在状态HTML中,但是,如果有任何关于这是否是正确的方法的反馈,我将不胜感激(我觉得这不太正确)。
仍然停留在如何在更新标记值时重新评估输出上。
您可以在ng-repeat
:上使用过滤器(docs)
<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;
}
我把你的小提琴叉在这里是为了展示这一点。
您处理这件事的方式有一个小问题,即项目有一个标签"名称"数组,而不是id。因此,这个例子只适用于标记名数组(我必须编辑一些初始数据以使其一致)。