可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a JSON object that contains an int property x
, I would like to repeat following code x times
<span class="glyphicon glyphicon-star"/>
ng-repeat does not seem to be indicated as it's working with collection.
Any suggestion (angular newbie)
回答1:
I would use custom filter with ng-repeat
:
HTML
<div ng-app='myApp' ng-controller="Main"> <li ng-repeat="n in [] | range:20"> <span class="glyphicon glyphicon-star" >{{n}}</span> </li> </div>
filter
app.filter('range', function() { return function(val, range) { range = parseInt(range); for (var i=0; i<range; i++) val.push(i); return val; }; });
Demo Fiddle
回答2:
Shortest answer: 2 lines of code
JS (in your AngularJS controller)
$scope.range = new Array(MAX_STARS); // MAX_STARS should be the most stars you will ever need in a single ng-repeat
HTML
<span class="glyphicon glyphicon-star" ng-repeat="i in range.slice(0,starCount) track by $index"/>
...where starCount
is the number of stars that should appear in this location.
回答3:
you can write filter range:
'use strict'; angular.module('app.Filter') .filter('range', function() { return function(input, total) { total = parseInt(total); for (var i=0; i < total; ++i) { input.push(i); } return input; }; });
then use it
<span class="glyphicon glyphicon-star" ng-repeat="i in [] | range:5"/>
5 its your x
回答4:
When I was first starting to play with AngularJS, I found a decent tutorial that walks you through making a custom directive for doing a "Rating" widget in Angularjs.
http://www.befundoo.com/university/tutorials/angularjs-directives-tutorial/
They don't do anything special other than create a collection of empty objects based on the value of a two-way bound scope variable defined in the directive.
directive('fundooRating', function () { return { restrict: 'A', template: '<ul class="rating">' + '<li ng-repeat="star in stars" class="filled">' + '\u2605' + '</li>' + '</ul>', scope: { ratingValue: '=' }, link: function (scope, elem, attrs) { scope.stars = []; for (var i = 0; i < scope.ratingValue; i++) { scope.stars.push({}); } } } });
The nice thing is that the collection messiness is at least encapsulated inside of the directive, and all the controller has to do is deal with the the numerical rating value. The tutorial also walks you through doing two way linking between the directive and the controller on the rating value scope variable.
IMHO, this is the cleanest solution since AngularJS doesn't directly support what you want to do. At least here, it is easy to understand what you are trying to do in your controller and view (which is where you want to avoid unnecessary complexity) and you move the hackish-ness into the directive (which you will probably write once and forget).
回答5:
Angular (V1.2.9 and up) includes a filter limitTo:n
that will do this out of the box. For example to limit ng-repeat
to the first 20 elements use the following syntax:
<div ng-app='myApp' ng-controller="Main"> <li ng-repeat="n in [] | limitTo:20"> <span class="glyphicon glyphicon-star" >{{n}}</span> </li> </div>
Documentation for limitTo is here
To be fair the limitTo
filter didn't exist at the time the original question was asked.
回答6:
I answered a similar (duplicate?) question https://stackoverflow.com/a/31864879/1740079. I'll just repost here as I also ended up here searching for an answer.
(function () { angular .module('app') .directive('repeatTimes', repeatTimes); function repeatTimes ($window, $compile) { return { link: link }; function link (scope, element, attrs) { var times = scope.$eval(attrs.repeatTimes), template = element.clone().removeAttr('repeat-times'); $window._(times).times(function (i) { var _scope = angular.extend(scope.$new(), { '$index': i }); var html = $compile(template.clone())(_scope); html.insertBefore(element); }); element.remove(); } } })();
... and the html:
<div repeat-times="4">{{ $index }}</div>
LIVE EXAMPLE