Używam dyrektywy ng-repeat z takim filtrem:
ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"
i widzę dobrze renderowane wyniki; teraz chcę uruchomić logikę na tym wyniku w moim kontrolerze. Pytanie brzmi, jak mogę pobrać odniesienie do elementów wyników?
Aktualizacja:
Dla wyjaśnienia: próbuję utworzyć autouzupełnianie, mam takie dane wejściowe:
<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">
a następnie przefiltrowane wyniki:
<ul>
<li ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li>
</ul>
teraz chcę przejść do wyniku i wybrać jedną z pozycji.
javascript
angularjs
filter
angularjs-ng-repeat
Shlomi Schwartz
źródło
źródło
filteredItems
, zawsze otrzymuję dane o jeden filtr później. To nie jest wynik zmienionego właśnie filtra, ale ten z poprzedniej zmiany. Jakieś pomysły?Oto filtracyjna wersja rozwiązania Andy'ego Joslina.
Aktualizacja: REWELACYJNA ZMIANA. Od wersji 1.3.0-beta.19 ( to zatwierdzenie ) filtry nie mają kontekstu i
this
będą powiązane z zakresem globalnym. Możesz przekazać kontekst jako argument lub użyć nowej składni aliasingu w 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); }; });
Wtedy twoim zdaniem
<!-- 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>
Co daje ci dostęp do
$scope.filteredItems
.źródło
$parse
jest kompilatorem wyrażeń Angulara. Na przykład, weźmie ciąg „some.object.property” i zwróci funkcję, która pozwala ustawić lub pobrać wartość na wspomnianej ścieżce dla określonej kontekst. Używam go konkretnie do ustawienia wyników filtru w zakresie $ scope. Mam nadzieję, że to odpowiada na twoje pytanie.Spróbuj czegoś takiego, problem z powtórzeniem ng polega na tym, że tworzy zakres potomny, ponieważ nie możesz uzyskać dostępu
ze sterownika
<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
źródło
Aktualizacja:
Nawet po 1.3.0. jeśli chcesz umieścić go na zakres kontrolera lub rodzica nie można tego zrobić z jak składni. Na przykład, jeśli mam następujący kod:
<div>{{labelResults}}</div> <li ng-repeat="label in (labels | filter:query | as labelResults)"> </div>
powyższe nie zadziała. Aby to obejść, użyj elementu $ parent w następujący sposób:
<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">
źródło
console.log labelResults
zawsze otrzymuję dane o jeden filtr później. To nie jest wynik zmienionego właśnie filtra, ale ten z poprzedniej zmiany. Nie miałeś tego problemu?Wymyśliłem nieco lepszą wersję rozwiązania Andy'ego. W swoim rozwiązaniu ng-repeat zwraca uwagę na wyrażenie zawierające przypisanie. Każda pętla podsumowania oceni to wyrażenie i przypisze wynik do zmiennej zakresu.
Problem z tym rozwiązaniem polega na tym, że możesz napotkać problemy z przypisaniem, jeśli jesteś w zakresie podrzędnym. To jest ten sam powód, dla którego powinieneś mieć kropkę w modelu ng .
Inną rzeczą, której nie lubię w tym rozwiązaniu, jest to, że zakopuje definicję przefiltrowanej tablicy gdzieś w znaczniku widoku. Jeśli jest używany w wielu miejscach w widoku lub kontrolerze, może być mylący.
Prostszym rozwiązaniem jest po prostu umieszczenie zegarka w kontrolerze na funkcji, która dokonuje przypisania:
$scope.$watch(function () { $scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4"); });
Ta funkcja będzie oceniana podczas każdego cyklu trawienia, więc wydajność powinna być porównywalna z rozwiązaniem Andy'ego. Możesz również dodać dowolną liczbę przypisań w funkcji, aby zachować je wszystkie w jednym miejscu, a nie rozproszone w widoku.
W widoku wystarczy bezpośrednio użyć przefiltrowanej listy:
<ul> <li ng-repeat="item in filteredItems">{{item.name}}</li> </ul>
Oto skrzypce, na których pokazano to w bardziej skomplikowanym scenariuszu.
źródło
Sprawdź odpowiedź:
Wybieranie i uzyskiwanie dostępu do elementów w ng-repeat
<li ng-repeat="item in ..." ng-click="select_item(item)">
źródło