当搜索为空时,搜索不起作用的角度ng-repeat

时间:2015-03-04 05:12:55

标签: angularjs angularjs-ng-repeat

我有以下内容:

<div ng-repeat="foo in foos | filter:search | orderBy:'fooName'">
   <input type="checkbox" id="cb-{{$index}}" ng-click="diseaseCheckboxClick($index)"/>
   <input type="hidden" id="foo-{{$index}}" value="{{foo.id}}"/>
   <label id="label-{{$index}}">{{foo.fooName}}</label>          
 </div>

'foos'的集合来自ReST电话。 一个人有一个'foos'的集合,我有一个循环遍历每个'foos'集合的函数,该函数的工作是检查'foo'与否。如果该人具有该特定的'foo',请勾选它。 我使用隐藏文本字段来保存fooIds,我将其用于比较。

for (var i = 0; i < $scope.person.foos.length; i++) {
   var outerFooId = $scope.person.foos[i].id;
   for (var j = 0; j < $scope.foos.length; j++) {
      var fooElem= '#foo-' + j;
      var fooIdValue = $(fooElem).val();
      if (outerFooId === fooIdValue) {
         var cbId= '#cb-' + j;
         $(cbId).attr('checked', true);
         break;
      }
    }
   }

我遇到的唯一问题是,当我输入一个带回零结果的搜索项(并且可以正常工作)时,但是当我退回并删除没有结果的搜索项时,用于选中复选框不起作用,这是由于调用'$(fooElem).val();'在函数中返回undefined。 我在页面中看到了列表,当我查看源代码时,我会看到所有字段,包括隐藏文本字段,包含fooId,所以我不知道为什么函数没有“看到”它。

请注意,只有在我输入的搜索结果没有结果,然后退格以清除搜索字段时才会出现这种情况。 搜索和标记复选框无效。

知道为什么会发生这种情况,或者我如何使该功能“看到”隐藏的文本字段。我会注意到我也尝试使用'label'元素,但结果相同,标签的文本未定义。

1 个答案:

答案 0 :(得分:1)

这不能完全解决你的问题,但我必须指出你正在犯混合方法的经典错误。在Angular中,您永远不应该有任何代码在指令之外操作DOM,即使这样也很少有必要。

这里有两条经典线索 - 您正在使用$()(jquery),并且您正在使用HTML DOM id属性。 Angular中唯一真正用于id的是将标签与输入元素(你在这里没有做)相关联,即使这样,在大多数情况下,你可以放弃在标签内包含输入而不是使用“label for”语法

说完所有这些,并且没有看到你的其余代码,这就是你如何“摇摆”你正在做的事情:

我将做一些假设(可能应该通过你的问题回答):

1)foos是所有foos的列表。每个foo都有一个唯一的id和名称。

2)一个人可以拥有一些或所有的泡沫。

3)您的代码的目的是允许某人查看他们拥有的foos,并按名称过滤列表。

首先,模型:

为了使事情变得快速(在检查每个foo时避免循环,foos应该通过id索引。当你从一个人加载它们时,你应该通过id创建一个地图:

var fooMap = {};
foreach(var i in person.foos) {
    fooMap[person.foos[i].id] = person.foos[i];
}

请注意,如果person.foos已经是id!

的地图,则可以简化此操作

您还需要控制器中的一些方法:

$scope.hasFoo(foo) {
    return fooMap[foo.id];
}

您的模板变为:

 <div ng-repeat="foo in foos | filter:search | orderBy:'fooName'">
   <label>{{foo.fooName}}<input type="checkbox" ng-click="diseaseCheckboxClick(foo)" ng-checked="hasFoo(foo)"/></label>     
 </div>

注意没有隐藏的输入,没有id - 只是一个由$ scope状态驱动的模板。

这将解决眼前的问题(搜索后丢失foos)。

这个难题的最后一部分是实现你的点击功能。如果不了解更多关于实际实现的内容,请参阅以下内容(您必须自己详细说明)。

$scope.diseaseCheckboxClick = function(foo) {
    if(fooMap[foo.id]) {
        //remove the foo from $scope.person.foos

        // and update fooMap
        delete fooMap[foo.id];
    }
    else {
        //add the foo to $scope.person.foos and update fooMap
        $scope.person.foos.push(foo);
        fooMap[foo.id] = foo;
    }
}

希望这能指出你正确的方向。我推断了很多,所以我确定我有一些错误,但你现在面临的关键问题是将jQuery和Angular混合在一起。