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

Shl*_*rtz 128 javascript filter angularjs angularjs-ng-repeat

我正在使用带有过滤器的ng-repeat指令,如下所示:

ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"
Run Code Online (Sandbox Code Playgroud)

我可以看到渲染结果很好; 现在我想在我的控制器中对该结果运行一些逻辑.问题是如何获取结果项引用?

更新:


只是为了澄清:我正在尝试创建一个自动完成,我有这个输入:

<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">
Run Code Online (Sandbox Code Playgroud)

然后过滤结果:

<ul>
   <li  ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

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

And*_*lin 268

更新:这是一个比以前更简单的方法.

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

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

  • 有人可以解释一下,为什么这有效?我可以理解,$ scope中的变量可以在重复范围(范围继承)中访问,但反过来呢?怎么样?一些文件表示赞赏.谢谢 (4认同)
  • 这种方法的问题在于,如果你观察分配的属性,你最终会发送垃圾邮件$摘要(每次迭代一次)...也许有一些方法可以避免这种情况? (3认同)

kev*_*s86 30

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

更新:突然变化.从版本1.3.0-beta.19(此提交)开始,过滤器没有上下文,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);
  };
});
Run Code Online (Sandbox Code Playgroud)

然后在你看来

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

这使您可以访问$scope.filteredItems.

  • @Magne没问题!请查看更新,因为它可以为您节省一些痛苦和痛苦.回答你的问题,简而言之,`$ parse`是Angular的[表达式编译器](https://docs.angularjs.org/api/ng/service/$parse).例如,它将采用字符串' some.object.property'并返回一个函数,允许您在指定上下文的所述路径上设置或获取值.我正在使用它在这里设置$ scope的过滤结果.我希望这回答了你的问题. (2认同)

ima*_*era 23

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

filteritems

来自控制器

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


Gal*_*cha 15

更新:

即使在1.3.0之后.如果你想要把它的控制器或家长的范围,你不能做到这一点与作为语法.例如,如果我有以下代码:

<div>{{labelResults}}</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>
Run Code Online (Sandbox Code Playgroud)

以上将无法正常工作.解决它的方法是使用$ parent,如下所示:

<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 10

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

此解决方案的问题在于,如果您在子范围内,则可能会遇到分配问题.这就是为什么你应该在ng-model中有一个点的原因.

我不喜欢这个解决方案的另一件事是它在视图标记中的某处隐藏了过滤数组的定义.如果它在视图或控制器中的多个位置使用,可能会让人感到困惑.

一个更简单的解决方案是在控制器中将一块手表放在一个执行赋值的函数上:

$scope.$watch(function () {
    $scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4");
});
Run Code Online (Sandbox Code Playgroud)

此功能将在每个摘要周期中进行评估,因此性能应与Andy的解决方案相当.您还可以在函数中添加任意数量的赋值,以将它们保存在一个位置而不是分散在视图中.

在视图中,您只需直接使用筛选列表:

<ul>
    <li  ng-repeat="item in filteredItems">{{item.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

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