javascript - array - AngularJS: cómo obtener una referencia de resultados filtrada ngRepeat
ng-repeat select (6)
Estoy usando una directiva ng-repeat con filtro así:
ng-repeat="item in items | orderBy:''order_prop'' | filter:query | limitTo:4"
y puedo ver los resultados representados bien; ahora quiero ejecutar un poco de lógica sobre ese resultado en mi controlador. La pregunta es ¿cómo puedo tomar la referencia de elementos de resultado?
Actualizar:
Solo para aclarar: estoy tratando de crear un autocompletar, tengo esta entrada:
<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">
y luego los resultados filtrados:
<ul>
<li ng-repeat="item in items | orderBy:''order_prop'' | filter:query | limitTo:4">{{item.name}}</li>
</ul>
ahora quiero navegar por el resultado y seleccionar uno de los elementos.
Aquí está la versión de filtro de la solución de Andy Joslin.
Actualización: CAMBIANDO EL CAMBIO. A partir de la versión 1.3.0-beta.19 ( este compromiso ) los filtros no tienen un contexto y this
estará ligado al alcance global. Puede pasar el contexto como argumento o usar la nueva sintaxis de aliasing en 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);
};
});
Entonces en tu vista
<!-- 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>
Lo que le da acceso a $scope.filteredItems
.
Intente algo como esto, el problema con la repetición ng es que crea el alcance del niño debido a que no puede acceder
filteritems
desde el controlador
<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
Se me ocurrió una versión algo mejor de la solución de Andy. En su solución ng-repeat coloca un reloj sobre la expresión que contiene la asignación. Cada ciclo de resumen evaluará esa expresión y asignará el resultado a la variable de ámbito.
El problema con esta solución es que puede encontrarse con problemas de asignación si se encuentra en un ámbito secundario. Esta es la misma razón por la que debería tener un punto en ng-model .
La otra cosa que no me gusta de esta solución es que entierra la definición de la matriz filtrada en algún lugar del margen de vista. Si se usa en varios lugares en su vista o en su controlador, puede resultar confuso.
Una solución más simple es simplemente colocar un reloj en su controlador en una función que hace la tarea:
$scope.$watch(function () {
$scope.filteredItems = $scope.$eval("items | orderBy:''order_prop'' | filter:query | limitTo:4");
});
Esta función se evaluará durante cada ciclo de digestión, por lo que el rendimiento debería ser comparable con la solución de Andy. También puede agregar cualquier cantidad de asignaciones en la función para mantenerlas todas en un solo lugar y no dispersas en la vista.
En la vista, solo usarías la lista filtrada directamente:
<ul>
<li ng-repeat="item in filteredItems">{{item.name}}</li>
</ul>
Aquí hay un violín donde esto se muestra en un escenario más complicado.
Verifique esta respuesta:
Seleccionar y acceder a los elementos en ng-repeat
<li ng-repeat="item in ..." ng-click="select_item(item)">
ACTUALIZACIÓN : Aquí hay una manera más fácil que lo que estaba allí antes.
<input ng-model="query">
<div ng-repeat="item in (filteredItems = (items | orderBy:''order_prop'' | filter:query | limitTo:4))">
{{item}}
</div>
Entonces $scope.filteredItems
es accesible.
Actualizar:
Incluso después de 1.3.0. si quiere ponerlo en el alcance del controlador o del padre, no puede hacerlo con la sintaxis. Por ejemplo, si tengo el siguiente código:
<div>{{labelResults}}</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>
lo anterior no funcionará. La forma de evitarlo es usar $ parent como tal:
<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">