angularjs - array - Expresiones angulares ng-repetidas como variables
ng-repeat select (3)
No puede usar ng-repeat con una cadena / variable que debe representar la expresión directamente, pero puede crear una directiva que interpole / analice este valor y lo pase al argumento ng-repeat y recompile el elemento.
app.directive(''ngVarRepeat'',function($compile){
return {
priority:1001, //must be higher than 1000 (priority of ng-repeat)
compile:function($elm,$attrs){
var expression = $attrs.ngVarRepeat;
$elm.removeAttr(''ng-var-repeat''); // remove attribute so we can recompile it later
return function(scope,elm,attrs){
$elm.attr(''ng-repeat'',scope.$eval(expression));
$compile($elm)(scope);
}
}
}
})
Eche un vistazo a este plunker: demo plunker de la respuesta aceptada
También tenga en cuenta que este enfoque debería causar problemas en las repeticiones ng anidadas.
Estoy tratando de hacer algo como esto:
<ul>
<li ng-repeat="{{myRepeatExpression}}">{{row.name}}</li>
</ul>
Pero debido a que la lógica de ng-repeat
está en el estado de compilación de la directiva, trata {{myRepeatExpression}}
como una cadena normal en lugar de una variable. Lo que no funciona, obviamente.
¿Hay alguna solución para eso?
Solo puede usar y expresión con ng-repeat
y no un valor interpolated
. Ahora, para crear una lista repetible dinámica, puede probar:
- utilizando una función que devuelve la lista dinámicamente en la
ng-repeat
; esto es potencialmente más costoso ya que angular necesita llamar a la función primero y luego determinar si la colección ha cambiado al realizar un ciclo de$digest
-
$watch
una variable en particular en el ámbito que desencadene un cambio de la lista; potencialmente más eficiente, pero si su lista dinámica depende de más de una variable, puede obtener más detalles y puede llevar a posibles errores a olvidarse de agregar un nuevo$watch
cuando se requiere una nueva variable
JS:
app.controller(''MainCtrl'', function($scope) {
var values1 = [{name:''First''}, {name:''Second''}];
var values2 = [{name:''Third''}, {name:''Fourth''}, {name:''Fifth''}];
//1. function way
$scope.getValues = function(id) {
if(id === 1) {
return values1;
}
if(id === 2) {
return values2;
}
}
//2. watch way
$scope.values = undefined;
$scope.$watch(''id'', function(newVal) {
$scope.values = $scope.getValues(newVal);
});
});
HTML:
<!-- Here we pass the required value directly to the function -->
<!-- this is not mandatory as you can use other scope variables and/or private variables -->
<ul>
<li ng-repeat="v in getValues(id)">{{v.name}}</li>
</ul>
<!-- Nothing special here, plain old ng-repeat -->
<ul>
<li ng-repeat="v in values">{{v.name}}</li>
</ul>
ng-repeat
solo lo acepta sintaxis de expresión propietaria como en row in rows
, pero las rows
pueden ser una función o promesa en su controlador. Sin embargo, debe observar el rendimiento con atención, ya que ng-repeat no funciona bien con cosas que cambian con demasiada frecuencia (el temido error de 10 iteraciones máximo).