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

时间:2012-07-30 12:45:00

标签: javascript angularjs filter angularjs-ng-repeat

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

现在我想导航结果并选择其中一个项目。

6 个答案:

答案 0 :(得分:264)

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

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

然后可以访问$scope.filteredItems

答案 1 :(得分:30)

以下是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

答案 2 :(得分:23)

尝试这样的事情,ng-repeat的问题在于它创建子范围,因为你无法访问

  

filteritems

来自控制器

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

答案 3 :(得分:15)

<强>更新

即使在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))">

答案 4 :(得分:10)

我想出了一个更好的安迪解决方案版本。在他的解决方案中,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.

答案 5 :(得分:-1)

检查这个答案:

Selecting and accessing items in ng-repeat

<li ng-repeat="item in ..." ng-click="select_item(item)">