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。
我有以下内容:
<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。