Ng-repeat on integer value
Solution 1
Checkout 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;
}
Change your html to following
<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>
Solution 2
I solved this in this way: "items" is your array of objects in the $scope, accesing the property "rating", you can show the star if the value is less or the same comparing to the "rating" property.
In this example I'm using some icon fonts but for the case of an image is the same thing.
<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>
I've found a better solution that solves this requirement at all:
https://github.com/fraserxu/ionic-rating
Solution 3
It looks like you are iterating on the pies
and that's where the $index
gets its value from.
Instead of ng-repeat="rating in ratings[$index]"
you should use ng-repeat="rating in range(pie.rating)"
This way, the rating would follow your pie when ordering.
Then you could completely remove the loop in the controller.
Could you provide just a bit more HTML so that we could see where the $index
comes from?
Regards, Camusensei
EDIT:
You are indeed iterating over pies.pies
in
ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp"
So what I wrote earlier should work. See below for exhaustive changes.
Controller:
$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: Sorry, I forgot the range function (inspired from Ariya Hidayat):
$scope.range = function(count){
return Array.apply(0, Array(+count));
}
Solution 4
The problem is that ng-repeat
only works with arrays or objects, so you can't say iterate x times (while x is a number)
A solution could be to write a function in JavaScript:
$scope.getNumber = function(num) {
return (new Array(num));
}
An then use this html to show the stars without $index:
<div ng-repeat="rating in getNumber(pie.rating)"></div>
Comments
-
Chrillewoodz almost 2 years
I'm trying to use
ng-repeat
on adiv
which should contain a star image, each pie in the JSON has arating
property from 1-5, and I want to use this value to loop out x number of stars. I've got this working somewhat but it's flawed in the way that I can't re-sort the array and make the stars follow the correct item in the list since I'm using[$index]
to track the iteration.My solution is rather ugly as well since I'm creating arrays with as many index placeholders as the value of the
rating
property, and then pushing this into an array to loop out the appropriate number of images. I would like to have a more elegant solution.How should I go about this problem without using
[$index]
?Snippet of the JSON:
{"pies": [ ... { "name": "Blueberry pie", "imageUrl": "img/blueberrypie.png", "id": "1", "rating": "5", //Ng-repeat depending on this value "description": "Blueberry pie is amazing." }, ... ]}
My controller:
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); }) }]);
The list which contains the pie items:
<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>
Outcome:
-
Chrillewoodz over 9 yearsHow do I pass the current rating value as a parameter though?
-
dhavalcengg over 9 yearsedited my answer. Now you don't need ratings array. Just pass pie.rating to range function. And you are good to go.
-
Chrillewoodz over 9 yearsHmm.. I got a bit of an odd one. When using +count I get no stars at all, if I use count I only get one. Any idea why? My solution is identical to yours.
-
dhavalcengg over 9 yearsuse other variable then rating in ng-repeat. Updated my answer.
-
Chrillewoodz over 9 yearsLook at my comment in the answer above.
-
dhavalcengg over 9 yearsThis could happen if your pie.rating is blank string. Can you check pie.rating again.?
-
Chrillewoodz over 9 yearsJust thought of that. Testing to see when integer hang on.
-
Chrillewoodz over 9 yearsDoesn't work at all when it's a number... What exactly does the + before count do?
-
dhavalcengg over 9 yearsLet us continue this discussion in chat.
-
Camusensei over 9 yearsFor debug purposes, use this range function:
$scope.range = function(count){var a = new Array(+count); console.log(count, a); return a;};
-
Chrillewoodz over 9 yearsWe solved it, still doesn't know what caused it to malfunction though. I will investigate this matter further.
-
Camusensei over 9 yearsOkay, I found out where the problem was : 2ality.com/2012/06/dense-arrays.html The array was sparse instead of dense
-
Chrillewoodz over 9 yearsInteresting, but I tried that solution but didn't work either. It feels like there's something else that's causing the malfunction. At least I've found a solution that works now ;S
-
Camusensei over 9 yearsOk great ^^ Have a nice day.
-
alphapilgrim over 8 yearshow would you add a class to this?