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

IT技术 javascript angularjs filter angularjs-ng-repeat
2021-01-21 11:37:55

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

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

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

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

这种方法的问题在于,如果您查看分配的属性,您最终会发送垃圾邮件 $digests(每次迭代一个)...也许有某种方法可以避免这种情况?
2021-03-16 11:37:55
有人可以解释一下,为什么这行得通?我可以理解 $scope 中的变量可以在重复作用域(作用域继承)中访问,但反过来呢?如何?一些文件表示赞赏。谢谢
2021-03-16 11:37:55
超级酷,谢谢你。我希望它是 NG 的内置功能
2021-03-25 11:37:55
感谢您的回复,请查看我的更新。您将如何实现,请注意,我在 init 上获得了整个项目列表
2021-03-27 11:37:55
如果我查看搜索对象和 console.log,filteredItems我总是在经过一个过滤器后才能获得数据。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。有任何想法吗?
2021-03-31 11:37:55

这是 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);
  };
});

那么在你看来

<!-- 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,角度文档也没有帮助我解码过滤器的工作原理。
2021-03-19 11:37:55
@Magne 没问题!请检查更新,因为它可能会为您节省一些痛苦和痛苦。简而言之,要回答您的问题,$parse是 Angular 的表达式编译器.. 例如,它将采用字符串 'some.object.property' 并返回一个函数,该函数允许您在指定的路径上设置或获取值语境。我正在使用它在这里的 $scope 上设置过滤器结果,特别是。我希望这回答了你的问题。
2021-04-09 11:37:55

尝试这样的事情,ng-repeat 的问题在于它创建了子作用域,因为您无法访问

过滤项目

从控制器

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

更新:

即使在 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))">
如果我console.log labelResults总是在稍后获得数据一个过滤器。这不是刚刚更改的过滤器的结果,而是上一次更改的结果。你没有这个问题吗?
2021-03-23 11:37:55
值得注意的是,如果您对此有一个 limitTo 过滤器。它不会反映在 $parent.labelResults 中
2021-04-09 11:37:55

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

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

这个解决方案对我来说是完美的..我使用的是ionic的collection repeat而不是ng repeat..这就是为什么接受的答案对我不起作用
2021-03-21 11:37:55
超级干净不污染结构,不错!
2021-03-25 11:37:55