Ответ 1
ОБНОВЛЕНИЕ. Здесь проще, чем раньше.
<input ng-model="query">
<div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
{{item}}
</div>
Тогда $scope.filteredItems
доступен.
Я использую директиву ng-repeat с фильтром следующим образом:
ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"
и я вижу, что полученные результаты прекрасны; теперь я хочу запустить некоторую логику этого результата в моем контроллере. Вопрос в том, как я могу получить ссылку на результат?
Update:
Просто чтобы уточнить: я пытаюсь создать автоматическое завершение, у меня есть этот ввод:
<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>
теперь я хочу перейти к результату и выбрать один из элементов.
ОБНОВЛЕНИЕ. Здесь проще, чем раньше.
<input ng-model="query">
<div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
{{item}}
</div>
Тогда $scope.filteredItems
доступен.
Здесь версия фильтра решения Энди Хослина.
Обновление: РАЗРЕШЕНИЕ ИЗМЕНЕНИЯ. Начиная с версии 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
.
Попробуйте что-то подобное, проблема с ng-repeat заключается в том, что он создает дочернюю область, из-за которой вы не можете получить доступ к
filteritems
с контроллера
<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
Update:
Даже после 1.3.0. если вы хотите поместить его в область действия контроллера или родителя, вы не можете сделать это с синтаксисом как. Например, если у меня есть следующий код:
<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))">
Я придумал несколько лучшую версию решения Энди. В своем решении ng-repeat помещает часы на выражение, которое содержит задание. Каждый цикл дайджеста будет оценивать это выражение и присваивать результат переменной области.
Проблема с этим решением заключается в том, что вы можете столкнуться с проблемами присваивания, если находитесь в дочерней области. Это по той же причине, почему у вас должна быть точка в ng-модели.
Другим, что мне не нравится в этом решении, является то, что он зарывает определение фильтрованного массива где-то в разметке представления. Если он используется в нескольких местах в вашем представлении или вашем контроллере, он может запутаться.
Более простым решением является просто установить часы в контроллере на функцию, которая выполняет назначение:
$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>
Отметьте этот ответ:
Выбор и доступ к элементам в ng-repeat
<li ng-repeat="item in ..." ng-click="select_item(item)">