AngularJS-如何获取ngRepeat过滤结果参考


129

我正在使用带有过滤器的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>

现在,我想浏览结果并选择其中一项。

Answers:


270

更新:这是一种比以前更简单的方法。

 <input ng-model="query">
 <div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
   {{item}}
 </div>

然后$scope.filteredItems是可访问的。


感谢您的答复,请参阅我的更新。您将如何实现这一点,请注意,我在init上获得了所有项目的清单
Shlomi Schwartz

超级酷,为此。我想这是一个建于NG的功能
施洛米施瓦茨

3
这种方法的问题在于,如果您观看分配的属性,最终将导致垃圾邮件$ digests(每个迭代一个)...也许有某种方法可以避免这种情况?
JuhoVepsäläinen13年

1
如果查看搜索对象和console.log filteredItems,则总是在以后的一个过滤器中获取数据。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。有任何想法吗?
ProblemsOfSumit

4
有人可以解释一下,为什么这样做?我可以理解,在重复作用域(作用域继承)中可以访问$ scope中的变量,但是相反吗?怎么样?一些文档表示赞赏。谢谢
dalvarezmartinez1

30

这是Andy Joslin解决方案的过滤器版本。

更新: BREAKING CHANGE。从1.3.0-beta.19版本开始(此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不熟悉,Angular文档也无法帮助我解码过滤器的工作原理。
Magne 2014年

2
@Magne没问题!请尽管检查此更新,但它可能会减轻您的痛苦和痛苦。简而言之,要回答您的问题$parse是Angular的表达式编译器 ..例如,它将使用字符串'some.object.property'并返回一个函数,该函数允许您在指定的路径处设置或获取值上下文。我正在使用它来在这里的$ scope上设置过滤器结果。我希望这回答了你的问题。
kevinjamesus86

23

尝试这样的操作,ng-repeat的问题在于它会创建子范围,因为您无法访问它

过滤项

从控制器

<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>

16

更新:

即使在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
Zack

如果我console.log labelResults总是在以后的一个过滤器中获取数据。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。你不是这个问题吗?
安娜

10

我想出了一个比Andy解决方案更好的版本。在他的解决方案中,ng-repeat监视包含该赋值的表达式。每个摘要循环将计算该表达式并将结果分配给scope变量。

该解决方案的问题在于,如果您在子范围内,则可能会遇到分配问题。这就是为什么您应该在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>

这是一个小提琴,在更复杂的场景中显示了这一点。


超级干净,不污染结构,不错!
kuzyn

这个解决方案对我来说是完美的..i我使用ionic的collection repeat而不是ng repeat ..这就是为什么被接受的答案对我不起作用
Lakshay

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.