validacion - tipos de funciones en javascript
Ng-repeticiĆ³n en valor entero (5)
El problema es que ng-repeat
solo funciona con matrices u objetos, por lo que no se puede decir iterar x veces (mientras que x es un número)
Una solución podría ser escribir una función en JavaScript:
$scope.getNumber = function(num) {
return (new Array(num));
}
Luego, use este html para mostrar las estrellas sin $ index:
<div ng-repeat="rating in getNumber(pie.rating)"></div>
Estoy tratando de usar ng-repeat
en un div
que debe contener una imagen de estrella, cada pastel en el JSON tiene una propiedad de rating
de 1 a 5, y quiero usar este valor para hacer un bucle de x número de estrellas. Tengo esto funcionando de alguna manera, pero tiene fallas en la forma en que no puedo reordenar la matriz y hacer que las estrellas sigan el elemento correcto en la lista ya que estoy usando [$index]
para rastrear la iteración.
Mi solución también es bastante fea, ya que estoy creando matrices con tantos marcadores de posición de índice como el valor de la propiedad de rating
, y luego la inserto en una matriz para completar el número adecuado de imágenes. Me gustaría tener una solución más elegante.
¿Cómo debo solucionar este problema sin usar [$index]
?
Fragmento del JSON:
{"pies": [
...
{
"name": "Blueberry pie",
"imageUrl": "img/blueberrypie.png",
"id": "1",
"rating": "5", //Ng-repeat depending on this value
"description": "Blueberry pie is amazing."
},
...
]}
Mi controlador
pieShopApp.controller(''shopCtrl'', [''$scope'', ''$http'', ''$routeParams'', function ($scope, $http, $routeParams) {
$scope.pieId = $routeParams.pieId,
$scope.sortingOptions = [''A-Z'', ''Rating''],
$scope.sortingValues = [''name'', ''rating''],
$scope.ratings = [],
$http.get(''jsons/pies.json'')
.success(function(data, status) {
$scope.pies = data;
for (i = 0; i < $scope.pies.pies.length; i++) {
switch ($scope.pies.pies[i].rating) {
case "1": $scope.ratings.push(["1"]); break;
case "2": $scope.ratings.push(["1", "2"]); break;
case "3": $scope.ratings.push(["1", "2", "3"]); break;
case "4": $scope.ratings.push(["1", "2", "3", "4"]); break;
case "5": $scope.ratings.push(["1", "2", "3", "4", "5"]); break;
}
}
console.log($scope.ratings);
})
.error(function(status) {
console.log(status);
})
}]);
La lista que contiene los elementos de la tarta:
<div id="pie-list-wrapper">
<ul class="nav">
<a href="#/pies/pieid" ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp">
<li class="list-item rounded-corners box-shadow">
<aside>
<img src="{{pie.imageUrl}}" no-repeat alt="Image of the pie">
</aside>
<header>
<h1 ng-bind="pie.name" id="item-name" class="bold-text"></h1>
</header>
<article>
<span ng-bind="pie.description" id="item-desc"></span>
</article>
<footer id="item-rating">
<div ng-repeat="rating in ratings[$index]" class="rating-box"></div> //Contains the stars
</footer>
</li>
</a>
</ul>
</div>
Salir:
En Angular 1.4+, obtienes el siguiente error al usar una matriz vacía:
Error: [ngRepeat: dupes] No se permiten duplicados en un repetidor.
Los siguientes trabajos:
$scope.range = function(count) {
return Array.apply(0, Array(+count)).map(function(value,index){
return index;
});
}
<div ng-app=''myApp'' ng-controller="Main">
<span ng-repeat="n in range(5)">Start{{$index}} </span>
</div>
Parece que estás iterando en las pies
y de ahí es donde el $index
obtiene su valor. En lugar de ng-repeat="rating in ratings[$index]"
, debe usar ng-repeat="rating in range(pie.rating)"
esta manera, la calificación seguirá su pie al hacer el pedido. Entonces podría eliminar completamente el bucle en el controlador.
¿Podría proporcionar un poco más de HTML para que podamos ver de dónde proviene el $index
?
Saludos, Camusensei
EDIT: De hecho, está iterando sobre pies.pies
en ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp"
Así que lo que escribí anteriormente debería funcionar. Vea abajo para cambios exhaustivos.
Controlador :
$http.get(''jsons/pies.json'')
.success(function(data, status) {
$scope.pies = data;
})
.error(function(status) {
console.log(status);
})
HTML :
<div ng-repeat="rating in range(pie.rating)" class="rating-box"></div>
EDIT2: Lo siento, olvidé la función de rango (inspirada en Ariya Hidayat ):
$scope.range = function(count){
return Array.apply(0, Array(+count));
}
Resolví esto de esta manera: "artículos" es su matriz de objetos en el $ scope, accediendo a la propiedad "rating", puede mostrar la estrella si el valor es menor o igual al de la propiedad "rating".
En este ejemplo, estoy usando algunas fuentes de iconos, pero para el caso de una imagen es lo mismo.
<div ng-repeat="item in items">
<div class="item-offers"">
<img ng-src="{{item.image}}">
<div class="item-not-rating">
<i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 1"></i>
<i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 2"></i>
<i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 3"></i>
<i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 4"></i>
<i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 5"></i>
</div>
</div>
</div>
He encontrado una mejor solución que resuelve este requisito en absoluto:
Revisa this
<div ng-app=''myApp'' ng-controller="Main">
<span ng-repeat="n in range(''5'')">Start{{$index}} </span>
</div>
$scope.range = function(count){
var ratings = [];
for (var i = 0; i < count; i++) {
ratings.push(i)
}
return ratings;
}
Cambia tu html a siguiente
<div id="pie-list-wrapper">
<ul class="nav">
<a href="#/pies/pieid" ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp">
<li class="list-item rounded-corners box-shadow">
<aside>
<img src="{{pie.imageUrl}}" no-repeat alt="Image of the pie">
</aside>
<header>
<h1 ng-bind="pie.name" id="item-name" class="bold-text"></h1>
</header>
<article>
<span ng-bind="pie.description" id="item-desc"></span>
</article>
<footer id="item-rating">
<div ng-repeat="start in range(pie.rating)" class="rating-box"></div> //Contains the stars
</footer>
</li>
</a>
</ul>
</div>