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>

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

4

6 回答 6

273

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

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

然后$scope.filteredItems就可以访问了。

于 2012-07-30T13:12:36.057 回答
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.

于 2013-08-09T14:56:13.667 回答
24

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

过滤项目

从控制器

<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
于 2015-01-11T08:56:45.803 回答
17

更新:

即使在 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))">
于 2016-01-07T15:06:39.340 回答
10

我想出了一个更好的安迪解决方案版本。在他的解决方案中,ng-repeat 对包含分配的表达式进行了监视。每个摘要循环都会评估该表达式并将结果分配给范围变量。

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

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

于 2014-12-17T15:21:55.213 回答
-2

检查这个答案:

在 ng-repeat 中选择和访问项目

<li ng-repeat="item in ..." ng-click="select_item(item)">
于 2016-02-25T19:07:32.983 回答