Angular ng-repeat with Search 在搜索为空时不起作用

Angular ng-repeat with Search not working when search is empty

我有以下内容:

<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',请勾选它。 我使用隐藏的文本字段来保存 fooId,我用它来进行比较。

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();'在函数 returns 未定义。 我在页面中看到了列表,当我查看源代码时,我看到了所有字段,包括包含 fooId 的隐藏文本字段,所以我不知道为什么函数没有 'see' 它。

请注意,这仅在我输入没有返回任何结果的搜索时发生,然后退格键清除搜索字段。 搜索和标记复选框以其他方式工作。

知道为什么会这样,或者我如何使函数 'see' 成为隐藏的文本字段。我会注意到,我也尝试使用 'label' 元素,但结果相同,标签文本未定义。

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

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

说完所有这些,在没有看到其余代码的情况下,这就是您 "angularize" 您正在做的事情:

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

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

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

3) 你的代码的目的是让别人看到他们有哪些 foos,并按名称过滤列表。

首先,模型:

为了加快速度(检查每个 foo 时避免循环,foo 应该按 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。