AngularJS - 如何获取 ngRepeat 过滤结果参考
Posted
技术标签:
【中文标题】AngularJS - 如何获取 ngRepeat 过滤结果参考【英文标题】:AngularJS - how to get an ngRepeat filtered result reference 【发布时间】:2012-07-28 03:25:09 【问题描述】:我正在使用带有过滤器的 ng-repeat 指令,如下所示:
ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"
我可以很好地看到渲染结果;现在我想在我的控制器中对该结果运行一些逻辑。问题是如何获取结果项引用?
更新:
澄清一下:我正在尝试创建一个自动完成,我有这个输入:
<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">
然后是过滤后的结果:
<ul>
<li ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">item.name</li>
</ul>
现在我想浏览结果并选择其中一项。
【问题讨论】:
【参考方案1】:检查这个答案:
Selecting and accessing items in ng-repeat
<li ng-repeat="item in ..." ng-click="select_item(item)">
【讨论】:
【参考方案2】:更新:
即使在 1.3.0 之后。如果你想把它放在控制器或父级的范围内,你不能用 as 语法来做到这一点。 例如,如果我有以下代码:
<div>labelResults</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>
以上将不工作。 绕过它的方法是使用 $parent :
<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">
【讨论】:
请注意,如果您对此有 limitTo 过滤器。它不会反映在 $parent.labelResults 如果我console.log labelResults
我总是在一个过滤器之后得到数据。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。你没有这个问题吗?【参考方案3】:
尝试这样的事情,ng-repeat 的问题在于它会创建子范围,因为您无法访问
过滤器
来自控制器
<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
【讨论】:
【参考方案4】:我想出了一个更好的 Andy 解决方案版本。在他的解决方案中,ng-repeat 对包含赋值的表达式进行了监视。每个摘要循环都会评估该表达式并将结果分配给范围变量。
此解决方案的问题是,如果您在子范围内,您可能会遇到分配问题。这也是为什么您应该拥有dot in ng-model 的原因。
我不喜欢这个解决方案的另一件事是它将过滤数组的定义隐藏在视图标记中的某处。如果在您的视图或控制器中的多个位置使用它可能会让人感到困惑。
一个更简单的解决方案是在你的控制器中放置一个手表来进行赋值:
$scope.$watch(function ()
$scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4");
);
将在每个摘要循环期间评估此函数,因此性能应该与 Andy 的解决方案相当。您还可以在函数中添加任意数量的分配,以将它们全部保存在一个位置,而不是分散在视图中。
在视图中,您可以直接使用过滤后的列表:
<ul>
<li ng-repeat="item in filteredItems">item.name</li>
</ul>
Here's a fiddle where this is shown in a more complicated scenario.
【讨论】:
超级干净不污染结构,不错! 这个解决方案对我来说是完美的..我使用 ionic 的集合重复而不是 ng 重复..这就是为什么接受的答案对我不起作用【参考方案5】:这是 Andy Joslin 解决方案的过滤器版本。
更新: 重大更改。从版本 1.3.0-beta.19 (this commit) 开始,过滤器没有上下文,this
将绑定到全局范围。您可以将上下文作为参数传递,也可以使用 ngRepeat, 1.3.0-beta.17+ 中的新别名语法。
// pre 1.3.0-beta.19
yourModule.filter("as", function($parse)
return function(value, path)
return $parse(path).assign(this, value);
;
);
// 1.3.0-beta.19+
yourModule.filter("as", function($parse)
return function(value, context, path)
return $parse(path).assign(context, value);
;
);
那么在你看来
<!-- pre 1.3.0-beta.19 -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:'filteredItems'">
item
</div>
<!-- 1.3.0-beta.19+ -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:this:'filteredItems'">
item
</div>
<!-- 1.3.0-beta.17+ ngRepeat aliasing -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 as filteredItems">
item
</div>
这使您可以访问$scope.filteredItems
。
【讨论】:
谢谢!你能解释一下过滤器代码是如何工作的吗?我不熟悉 $parse,角度文档并没有帮助我解码你的过滤器是如何工作的。 @Magne 没问题!请查看更新,因为它可能会为您节省一些痛苦和痛苦。要回答您的问题,简而言之,$parse
是 Angular 的 expression compiler.. 例如,它将采用字符串 'some.object.property' 并返回一个函数,该函数允许您设置或获取值指定上下文的路径。我正在使用它在这里的 $scope 上设置过滤器结果,特别是。我希望这能回答你的问题。【参考方案6】:
更新:这是一种比以前更简单的方法。
<input ng-model="query">
<div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
item
</div>
那么$scope.filteredItems
就可以访问了。
【讨论】:
感谢回复,请看我的更新。您将如何实现,请注意我在 init 上获得了整个项目列表 超级酷,谢谢。我希望它是 NG 的内置功能 这种方法的问题是,如果您查看分配的属性,您最终会向 $digests 发送垃圾邮件(每次迭代一个)......也许有一些方法可以避免这种情况? 如果我查看搜索对象和 console.logfilteredItems
我总是会在一个过滤器之后获得数据。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。有什么想法吗?
谁能解释一下,为什么会这样?我可以理解 $scope 中的变量可以在重复范围(范围继承)中访问,但反过来呢?如何?一些文档表示赞赏。谢谢以上是关于AngularJS - 如何获取 ngRepeat 过滤结果参考的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS:根据ngModel未使用ngRepeat选择单选按钮
angularjs基础ng-repeat嵌套循环报错angular.min.js:89 Error: [ngRepeat:dupes]