Есть ли способ ng-повторить определенное количество раз вместо того, чтобы всегда выполнять итерацию по массиву?
Например, ниже я хочу, чтобы элемент списка отображался 5 раз, предполагая $scope.number
равным 5, дополнительно увеличивая число, чтобы каждый элемент списка увеличивался, как 1, 2, 3, 4, 5
Желаемый результат:
<ul>
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
</ul>
В настоящий момент ng-repeat
принимает только коллекцию в качестве параметра, но вы можете сделать это:
<ul>
<li ng-repeat="i in getNumber(number)"><span>{{$index+1}}</span></li>
</ul>
И где-то в вашем контроллере:
$scope.number = 5;
$scope.getNumber = function(num) {
return new Array(num);
}
Это позволит вам изменить $scope.number
на любое число, по вашему усмотрению, и по-прежнему поддерживать привязку, которую вы ищете.
Вот скрипка с несколькими списками, использующими ту же функцию getNumber
.
EDIT 1/6/2014. Более новые версии Angular используют следующий синтаксис:
<li ng-repeat="i in getNumber(number) track by $index">
вы можете сделать это:
<div ng-repeat="i in [1, 2, 3, 4]">
...
</div>
Вот пример того, как вы могли это сделать. Обратите внимание, что я был вдохновлен комментарием в документах ng-repeat: http://jsfiddle.net/digitalzebra/wnWY6/
Обратите внимание на директиву ng-repeat:
<div ng-app>
<div ng-controller="TestCtrl">
<div ng-repeat="a in range(5) track by $index">{{$index + 1}}</div>
</div>
</div>
Вот контроллер:
function TestCtrl($scope) {
$scope.range = function(n) {
return new Array(n);
};
};
_.range
из Underscore или lodash для создания массива: $ scope.range = _.range (0, n);
Я думаю, что этот jsFiddle из этого потока может быть тем, что вы ищете.
<div ng-app ng-controller="Main">
<div ng-repeat="item in items | limitTo:2">
{{item.name}}
</div>
</div>
Я столкнулся с той же проблемой. Я наткнулся на эту тему, но мне не нравились методы, которые у них были здесь. Моим решением было использование underscore.js, которое мы уже установили. Это так просто:
<ul>
<li ng-repeat="n in _.range(1,6)"><span>{{n}}</span></li>
</ul>
Это сделает то, что вы ищете.
$scope._ = _
.
$rootScope
чтобы его можно было использовать везде. Поместите это в функцию app.run
сразу после app.config
: app.run(function ($rootScope) { $rootScope._ = _; });
Я хочу, чтобы мой html был очень минимальным, поэтому был определен небольшой фильтр, который создает массив [0,1,2,...], как это делали другие:
angular.module('awesomeApp')
.filter('range', function(){
return function(n) {
var res = [];
for (var i = 0; i < n; i++) {
res.push(i);
}
return res;
};
});
После этого в представлении можно использовать вот так:
<ul>
<li ng-repeat="i in 5 | range">
{{i+1}}
<li>
</ul>
Это действительно UGLY, но он работает без контроллера либо для целого числа, либо для переменной:
целое число:
<span ng-repeat="_ in ((_ = []) && (_.length=33) && _) track by $index">{{$index}}</span>
переменная:
<span ng-repeat="_ in ((_ = []) && (_.length=myVar) && _) track by $index">{{$index}}</span>
Более простой подход был бы (пример 5 раз):
<div ng-repeat="x in [].constructor(5) track by $index">
...
</div>
Есть много способов сделать это. Я действительно беспокоился о том, что у меня есть логика в контроллере, поэтому я создал простую директиву для решения проблемы повторения элемента n-times.
Установка:
Директива может быть установлена с помощью bower install angular-repeat-n
Пример:
<span ng-repeat-n="4">{{$index}}</span
производит: 1234
Он также работает с использованием переменной области видимости:
<span ng-repeat-n="repeatNum"></span>
Источник:
Это лишь незначительная вариация принятого ответа, но вам действительно не нужно создавать новую функцию. Только для импорта "Массив" в области:
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<ul>
<li ng-repeat="i in counter(5) track by $index">
<span>{{$index+1}}</span></li>
</ul>
</div>
</div>
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.myNumber = 5;
$scope.counter = Array;
});
Посмотрите эту скрипту для живого примера.
JS (в вашем контроллере AngularJS)
$scope.range = new Array(MAX_REPEATS); // set MAX_REPEATS to the most repetitions you will ever need in a single ng-repeat that makes use of this strategy
HTML
<div ng-repeat="i in range.slice(0,repeatCount) track by $index"></div>
... где repeatCount
- количество повторений, которые должны появляться в этом местоположении.
repeatCount
на фактическое число в HTML, и если это число меньше или равно MAX_REPEATS
, это позволит вам установить количество повторений в HTML.
angular дает очень слабую функцию под названием slice. Используя это, вы можете добиться того, что ищете. например ng-repeat = "ab в abc.slice(startIndex, endIndex)"
это демо: http://jsfiddle.net/sahilosheal/LurcV/39/ поможет вам и расскажет вам, как использовать эту функцию "сделать жизнь проще".:)
HTML:
<div class="div" ng-app >
<div ng-controller="Main">
<h2>sliced list(conditional NG-repeat)</h2>
<ul ng-controller="ctrlParent">
<li ng-repeat="ab in abc.slice(2,5)"><span>{{$index+1}} :: {{ab.name}} </span></li>
</ul>
<h2>unsliced list( no conditional NG-repeat)</h2>
<ul ng-controller="ctrlParent">
<li ng-repeat="ab in abc"><span>{{$index+1}} :: {{ab.name}} </span></li>
</ul>
</div>
CSS
ul
{
list-style: none;
}
.div{
padding:25px;
}
li{
background:#d4d4d4;
color:#052349;
}
нг-JS:
function ctrlParent ($scope) {
$scope.abc = [
{ "name": "What we do", url: "/Home/AboutUs" },
{ "name": "Photo Gallery", url: "/home/gallery" },
{ "name": "What we work", url: "/Home/AboutUs" },
{ "name": "Photo play", url: "/home/gallery" },
{ "name": "Where", url: "/Home/AboutUs" },
{ "name": "playground", url: "/home/gallery" },
{ "name": "What we score", url: "/Home/AboutUs" },
{ "name": "awesome", url: "/home/gallery" },
{ "name": "oscar", url: "/Home/AboutUs" },
{ "name": "american hustle", url: "/home/gallery" }
];
}
function Main($scope){
$scope.items = [{sort: 1, name: 'First'},
{sort: 2, name: 'Second'},
{sort: 3, name: 'Third'},
{sort: 4, name:'Last'}];
}
Получает ответ для angular 1.2.x
В принципе, это одно и то же, с небольшой модификацией ng-repeat
<li ng-repeat="i in getNumber(myNumber) track by $index">
вот скрипка: http://jsfiddle.net/cHQLH/153/
это потому, что angular 1.2 не позволяет дублировать значения в директиве. Это означает, что если вы пытаетесь сделать следующее, вы получите сообщение об ошибке.
<li ng-repeat="x in [1,1,1]"></li>
Вы можете использовать директиву ng-if
с ng-repeat
Итак, если num - это количество раз, которое вам нужно повторить элемент:
<li ng-repeat="item in list" ng-if="$index < num">
ng-repeat
все равно будут выводиться его закомментированные теги ( <!-- ngIf: $index < num -->
т. Д.). Для DOM просто не будет никаких li
элементов для рендеринга. Проверьте «просмотр источника» на панели результатов здесь, чтобы понять, что я имею в виду.
Сначала создайте фильтр angular, используя LoDash:
angular.module('myApp').filter('times', function(){
return function(value){
return _.times(value || 0);
}
});
Функция времени LoDash способна обрабатывать нулевые, undefined, 0, числа и строковое представление чисел.
Затем используйте его в своем HTML как это:
<span ng-repeat="i in 5 | times">
<!--DO STUFF-->
</span>
или
<span ng-repeat="i in myVar | times">
<!--DO STUFF-->
</span>
Для пользователей, использующих CoffeeScript, вы можете использовать понимание диапазона:
Директива
link: (scope, element, attrs) ->
scope.range = [1..+attrs.range]
или контроллер
$scope.range = [1..+$someVariable]
$scope.range = [1..5] # Or just an integer
Шаблон
<div ng-repeat="i in range">[ the rest of your code ]</div>
Вы можете использовать этот пример.
Внутренний контроллер:
$scope.data = {
'myVal': 33,
'maxVal': 55,
'indexCount': function(count) {
var cnt = 10;
if (typeof count === 'number') {
cnt = count;
}
return new Array(cnt);
}
};
Пример для элемента select со стороны HTML-кода:
<select ng-model="data.myVal" value="{{ data.myVal }}">
<option ng-repeat="i in data.indexCount(data.maxVal) track by $index" value="{{ $index + 1 }}">{{ $index + 1 }}</option>
</select>
Если n не слишком высоко, другим вариантом может быть использование split ('') со строкой из n символов:
<div ng-controller="MainCtrl">
<div ng-repeat="a in 'abcdefgh'.split('')">{{$index}}</div>
</div>
простой способ:
public defaultCompetences: Array<number> = [1, 2, 3];
в компоненте/контроллере, а затем:
<div ng-repeat="i in $ctrl.defaultCompetences track by $index">
Этот код из моего проекта typescript, но может быть перестроен на чистый javascript
Я создаю директиву многократного использования, где максимальное число будет получено из другого ng-repeat. Таким образом, это редактирование по лучшему проголосовавшему ответу.
Просто измените код на контроллере на это -
$scope.getNumber = function(num) {
var temp = [];
for(var j = 0; j < num; j++){
temp.push(j)
}
return temp;
}
Это вернет новый массив с указанным числом итераций
Я столкнулся с той же проблемой, и это то, с чем я вышел:
(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();
}
}
})();
... и html:
<div repeat-times="4">{{ $index }}</div>
Я использовал функцию подчеркивания times
, поскольку мы уже использовали ее в проекте, но вы можете легко заменить ее с помощью собственного кода.
поскольку итерация по строке будет отображать элемент для каждого char:
<li ng-repeat = "k in 'aaaa' track by $index">
{{$index}} //THIS DOESN'T ANSWER OP QUESTION. Read below.
</li>
мы можем использовать этот уродливый, но обходной код без кода, используя собственный фильтр number|n decimal places
.
<li ng-repeat="k in (0|number:mynumber -2 ) track by $index">
{{$index}}
</li>
таким образом у нас будут элементы mynumber
без дополнительного кода. Скажите '0.000'
.
Мы используем mynumber - 2
для компенсации 0.
Он не будет работать для чисел ниже 3, но может быть полезен в некоторых случаях.
track by $index
?
Angular предоставляет фильтры для изменения коллекции. В этом случае коллекция будет нулевой, т.е. [], И фильтр также принимает аргументы следующим образом:
<div id="demo">
<ul>
<li ng-repeat="not in []|fixedNumber:number track by $index">{{$index}}</li>
</ul>
</div>
JS:
module.filter('fixedNumber', function() {
return function(emptyarray, number) {
return Array(number);
}
});
module.controller('myCtrl', ['$scope', function($scope) {
$scope.number = 5;
}]);
Этот метод очень похож на предложенный выше и не обязательно превосходит, но показывает мощность фильтров в AngularJS.
Мне нужно было более динамичное решение - где я мог бы увеличивать повторение.
HTML
<div ng-repeat="n in newUserCount">
<input type="text" value="" name="newuser{{n}}"/>
</div>
Управление дубликатором
<span class="helper" ng-click="duplicateUser()">
Create another user with the same permissions
</span>
JS
$scope.newUserCount = Array('1');
var primaryValue = 1;
$scope.duplicateUser = function()
{
primaryValue++;
$scope.newUserCount.push(primaryValue)
}