नंबर और रेंज के साथ लूप के लिए कोणीयुलर


252

कोणीय अपने HTML निर्देशों में संख्याओं का उपयोग करते हुए लूप के लिए कुछ सहायता प्रदान करता है:

<div data-ng-repeat="i in [1,2,3,4,5]">
  do something
</div>

लेकिन अगर आपके स्कोप वैरिएबल में एक रेंज शामिल है जिसमें एक डायनेमिक नंबर है तो आपको हर बार एक खाली एरे तैयार करना होगा।

कंट्रोलर में

var range = [];
for(var i=0;i<total;i++) {
  range.push(i);
}
$scope.range = range;

HTML में

<div data-ng-repeat="i in range">
  do something
</div>

यह काम करता है, लेकिन यह अनावश्यक है क्योंकि हम लूप के भीतर रेंज सरणी का उपयोग नहीं करेंगे। क्या किसी को न्यूनतम / अधिकतम मूल्य के लिए सीमा निर्धारित करने या नियमित करने का पता है?

कुछ इस तरह:

<div data-ng-repeat="i in 1 .. 100">
  do something
</div>

2
यहाँ इस बारे में कुछ और जानकारी दी गई है। yearofmoo.com/2012/10/…
matsko

जवाबों:


280

मैंने इस जवाब को थोड़ा घुमा दिया और इस फील के साथ आया ।

फ़िल्टर के रूप में परिभाषित:

var myApp = angular.module('myApp', []);
myApp.filter('range', function() {
  return function(input, total) {
    total = parseInt(total);

    for (var i=0; i<total; i++) {
      input.push(i);
    }

    return input;
  };
});

इस तरह से दोहराए जाने के साथ:

<div ng-repeat="n in [] | range:100">
  do something
</div>

दिलचस्प है कि मुझे क्रोम का उपयोग करके फ़िडल में कोई त्रुटि नहीं दिखाई देती है। कौन सा ब्राउज़र?
ग्लॉपी

5
भयंकर! ;) एक फिल्टर ऐसा करने का तरीका नहीं है। यह एक नई विशेषता होनी चाहिए जो दो मूल्यों के साथ काम करती है । वर्तमान सूचकांक और ऊपरी सीमा।
इयान वारबर्टन

10
@IanWarburton क्या आप एक उत्तर के साथ आने में सक्षम हैं जो आपके मानदंडों को पूरा करता है?
'14:35

1
@IanWarburton: नीचे दिए गए निर्देशों के अनुसार काम करने वाला एक उत्तर है, आप इसे काम नहीं कर सकते।
एंड्रेस सेरज

1
मुझे A और B के बीच एक सीमा की आवश्यकता थी, इसलिए मैंने इस उत्तर को jsfiddle.net/h9nLc8mk
Marcio

150

मैं एक और भी सरल संस्करण के साथ आया, दो परिभाषित संख्याओं के बीच एक सीमा बनाने के लिए, जैसे। 5 से 15

JSFiddle पर डेमो देखें

HTML :

<ul>
    <li ng-repeat="n in range(5,15)">Number {{n}}</li>
</ul>

नियंत्रक :

$scope.range = function(min, max, step) {
    step = step || 1;
    var input = [];
    for (var i = min; i <= max; i += step) {
        input.push(i);
    }
    return input;
};

14
आपको इस तरह की चीजों के लिए बाहर देखना होगा। रेंज फ़ंक्शन को सूची में प्रत्येक आइटम के लिए कई बार कॉल किया जाएगा। आप गंदा मेमोरी लीक प्राप्त कर सकते हैं और आप बहुत सारे फ़ंक्शन कॉल कर रहे हैं। नियंत्रक के अंदर संग्रह को रखना लगभग आसान लगता है।
लुकास होल्ट

1
var a; void 0 === a"सही मायने में" अपरिभाषित।
andlrc

1
आप मेमोइज़र पैटर्न के माध्यम से परिणामों को कैशिंग करके पूर्ण हिट को कम कर सकते हैं। निश्चित नहीं है कि मेमोरी की लागत क्या है, लेकिन यह एक सुधार है। en.wikipedia.org/wiki/Memoization
जोशुआ

1
@LucasHolt अंत में इस उदाहरण को अद्यतन करने के लिए चारों ओर हो गया। मैंने एक अनुकूलित संस्करण जोड़ा है। इसमें अभी भी कई फ़ंक्शन कॉल होंगे, लेकिन यह पहले परिणाम का फिर से उपयोग करेगा जो इसे बहुत अधिक प्रदर्शनशील बनाता है।
sqren

93

सादे जावास्क्रिप्ट के अलावा और कुछ नहीं (आपको नियंत्रक की भी आवश्यकता नहीं है):

<div ng-repeat="n in [].constructor(10) track by $index">
    {{ $index }}
</div>

मॉकअप करते समय बहुत उपयोगी


कोणीय> 1.2.1 में काम नहीं कर रहा: मुझे यह त्रुटि कंसोल में मिली है Referencing "constructor" field in Angular expressions is disallowed! Expression: [].constructor(10)। हो सकता है कि यह कोणीय के पिछले संस्करण में काम कर रहा था या मैं कुछ गलत कर रहा हूं।
एडॉल्फ

मुझे लगता है कि मैंने 1.3 या 1.4 पर यह परीक्षण किया और यह ठीक था। मेरा मानना ​​है कि उन्होंने पार्सर में सुधार किया है, इसलिए यह हर 'कंस्ट्रक्टर' की पहुंच को अस्वीकार नहीं करता है, लेकिन केवल वास्तव में खतरनाक हैं (जैसे कि [].slice.constructor, जो एक्सेस देता है Function, इसलिए कोड मूल्यांकन के लिए)।
माएल नाइसन

ठीक है धन्यवाद। मैंने इसे 1.2.1 के साथ परीक्षण किया और यह काम नहीं कर रहा था (संस्करण jsFiddle ड्रॉपडाउन में शामिल है)। लेकिन 1.3.15 के साथ यह काम कर रहा है। इस jsFiddle देखें ।
एडोल्फ

महामारी के लिए बहुत उपयोगी है। धन्यवाद;)
अजनबी

69

मैं थोड़ा अलग वाक्यविन्यास के साथ आया जो मुझे थोड़ा अधिक सूट करता है और साथ ही एक वैकल्पिक निचली सीमा को जोड़ता है:

myApp.filter('makeRange', function() {
        return function(input) {
            var lowBound, highBound;
            switch (input.length) {
            case 1:
                lowBound = 0;
                highBound = parseInt(input[0]) - 1;
                break;
            case 2:
                lowBound = parseInt(input[0]);
                highBound = parseInt(input[1]);
                break;
            default:
                return input;
            }
            var result = [];
            for (var i = lowBound; i <= highBound; i++)
                result.push(i);
            return result;
        };
    });

जो आप के रूप में उपयोग कर सकते हैं

<div ng-repeat="n in [10] | makeRange">Do something 0..9: {{n}}</div>

या

<div ng-repeat="n in [20, 29] | makeRange">Do something 20..29: {{n}}</div>

यह बहुत अच्छा है, लेकिन $digestस्कूप्ड वैल्यू का उपयोग करते समय आपको सभी पुनरावृत्तियों के आसपास कैसे मिलता है , अर्थात ng-repeat="n in [1, maxValue] | makeRange":?
pspahn

एक और दो परम मामले हाईबाउंड का अलग तरह से इलाज करते हैं, यह सुसंगत होना चाहिए
वाजेक हर्मीज़

31

उन नए कोणीय के लिए। $ सूचकांक का उपयोग करके सूचकांक प्राप्त किया जा सकता है।

उदाहरण के लिए:

<div ng-repeat="n in [] | range:10">
    do something number {{$index}}
</div>

जब आप ग्लॉपी के आसान फ़िल्टर का उपयोग कर रहे हैं, तो प्रिंट करें:
कुछ नंबर 0
करें, कुछ नंबर 1
करें, कुछ नंबर 2
करें, कुछ नंबर 3
करें, कुछ नंबर 4
करें, कुछ नंबर 5
करें, कुछ नंबर 6 पर
करें, कुछ नंबर 7 पर कुछ करें, नंबर 7 पर
कुछ करें।
कुछ नंबर 9 करो


7
सच है, लेकिन इस मामले में do something number {{n}}भी पर्याप्त होगा।
कैप्टनक्रिग

2
जब मैं क्रोम में इस कोड को चलाने का प्रयास करता हूं, तो मुझे कंसोल में एक त्रुटि मिलती है: त्रुटि: [$ इंजेक्टर: unpr] त्रुटियाँ . angularjs.org/1.2.6/$injector/… ... ... Wa.statements पर ( ajax.googleapis.com/ajax/libs/angularjs/1.2.6/… ) <! - ngRepeat: n in [] | रेंज: 10 -> (दुर्भाग्य से पूरी त्रुटि की अनुमति दी गई टिप्पणी की लंबाई में फिट होने के लिए बहुत लंबा है इसलिए मैंने पहली और आखिरी पंक्ति की नकल की)
कैमिक्नर

1
मैंने कोड का एक प्लंकेर उदाहरण बनाया है ताकि आप इसे अपने कोड से तुलना कर सकें। plnkr.co/edit/tN0156hRfX0M6k9peQ2C?p=preview
अर्नॉड सेसेटेमा

21

ऐसा करने का एक छोटा तरीका अंडरस्कोर का उपयोग करना होगा। जेएस की _.range () विधि। :)

http://underscorejs.org/#range

// declare in your controller or wrap _.range in a function that returns a dynamic range.
var range = _.range(1, 11);

// val will be each number in the array not the index.
<div ng-repeat='val in range'>
    {{ $index }}: {{ val }}
</div>

1
@ वुडवर्ड वह कभी नहीं कहा कि एक विकल्प नहीं था। मेरा समाधान उनके रेपो से इकाई परीक्षण के लिए अब तक का सबसे सरल और सबसे अधिक परीक्षित धन्यवाद है। आप हमेशा गैर-पंजीकृत लाइब्रेरी से js ले सकते हैं और इसे एक फ़ंक्शन के रूप में शामिल कर सकते हैं।
माइकल जे। कैलकिंस

4
सच है, उन्होंने ऐसा कभी नहीं कहा। लेकिन आमतौर पर एक पुस्तकालय में एक समस्या को हल करने के लिए एक और पुस्तकालय को लागू करना एक बुरा विचार है, यह सिर्फ आपको सीखने से रोकता है कि पहले पुस्तकालय का सही उपयोग कैसे करें। चालू / एक अच्छा समाधान नहीं होने पर दूसरी लाइब्रेरी की ओर रुख करें।
एरिक होन

5
मैं पहले से ही हर जगह लॉश का उपयोग करता हूं, यह अब तक का सबसे आसान समाधान था। धन्यवाद। मैंने अभी $ गुंजाइश की है। अरेंज = _। अरेंज, फिर डायनामिक स्टार्ट / एंड वैल्यू वाले किसी भी टेम्प्लेट में इसका उपयोग करना आसान है।
j_walker_dev

2
@ ErikHonn: अंडरस्कोरजेस AngularJS के लिए एक पूरी तरह से अलग समस्या हल करता है। AngularJS में पर्वतमाला बनाने के लिए कोई अच्छा समाधान नहीं है क्योंकि यह पुस्तकालय का उद्देश्य नहीं है।
एलेक्सफॉक्सगिल

2
यह पुराना है, लेकिन निश्चित रूप से एक पुस्तकालय बनाने के लिए डिज़ाइन किया गया है जो एक सीमा बनाने जैसी चीज़ों का उपयोग कर रहा है, इसके बजाय गैर-अर्थ तरीके से आपके वर्तमान पुस्तकालय में एक सुविधा का दुरुपयोग करना कहीं बेहतर तरीका है? यकीन है कि आप कुछ सीख सकते हैं, लेकिन आप कुछ और के लिए डिज़ाइन की गई चीजों के विकृत उपयोग के साथ समाप्त होते हैं।
दान

20

मैं अपने कस्टम ng-repeat-rangeनिर्देश का उपयोग करता हूं :

/**
 * Ng-Repeat implementation working with number ranges.
 *
 * @author Umed Khudoiberdiev
 */
angular.module('commonsMain').directive('ngRepeatRange', ['$compile', function ($compile) {
    return {
        replace: true,
        scope: { from: '=', to: '=', step: '=' },

        link: function (scope, element, attrs) {

            // returns an array with the range of numbers
            // you can use _.range instead if you use underscore
            function range(from, to, step) {
                var array = [];
                while (from + step <= to)
                    array[array.length] = from += step;

                return array;
            }

            // prepare range options
            var from = scope.from || 0;
            var step = scope.step || 1;
            var to   = scope.to || attrs.ngRepeatRange;

            // get range of numbers, convert to the string and add ng-repeat
            var rangeString = range(from, to + 1, step).join(',');
            angular.element(element).attr('ng-repeat', 'n in [' + rangeString + ']');
            angular.element(element).removeAttr('ng-repeat-range');

            $compile(element)(scope);
        }
    };
}]);

और html कोड है

<div ng-repeat-range from="0" to="20" step="5">
    Hello 4 times!
</div>

या केवल

<div ng-repeat-range from="5" to="10">
    Hello 5 times!
</div>

या यहां तक ​​कि बस

<div ng-repeat-range to="3">
    Hello 3 times!
</div>

या केवल

<div ng-repeat-range="7">
    Hello 7 times!
</div>

1
सैद्धांतिक रूप से अच्छा है, लेकिन इंजेक्शन element.attr('ng-repeat', 'n in [' + rangeString + ']');काम नहीं करता है ...
स्टीफन वाल्थर

"मैं उपयोग करता हूं..."। क्या आपने वास्तव में इसका उपयोग करने की कोशिश की है? एनजी-रिपीट विशेषता संकलित नहीं की जाएगी।
पीटर हडबर्ग सेप

धन्यवाद पीटर, Ive कोड को अपडेट किया। मैंने अतीत में इस निर्देश का उपयोग किया था, लेकिन इसने अभी भी मेरे कोड रिपॉजिटरी को छोड़ दिया
pleerock

9

सबसे सरल कोई कोड समाधान रेंज के साथ एक सरणी में प्रवेश करने के लिए था, और $ इंडेक्स + का उपयोग करें हालांकि मैं इससे ऑफसेट करना चाहता हूं:

<select ng-init="(_Array = []).length = 5;">
    <option ng-repeat="i in _Array track by $index">{{$index+5}}</option>
</select>

7

विधि की परिभाषा

नीचे दिया गया कोड range()आपके आवेदन के पूरे दायरे के लिए उपलब्ध एक विधि को परिभाषित करता है MyApp। इसका व्यवहार पायथन range()विधि के समान है ।

angular.module('MyApp').run(['$rootScope', function($rootScope) {
    $rootScope.range = function(min, max, step) {
        // parameters validation for method overloading
        if (max == undefined) {
            max = min;
            min = 0;
        }
        step = Math.abs(step) || 1;
        if (min > max) {
            step = -step;
        }
        // building the array
        var output = [];
        for (var value=min; value<max; value+=step) {
            output.push(value);
        }
        // returning the generated array
        return output;
    };
}]);

प्रयोग

एक पैरामीटर के साथ:

<span ng-repeat="i in range(3)">{{ i }}, </span>

0, 1, 2,

दो मापदंडों के साथ:

<span ng-repeat="i in range(1, 5)">{{ i }}, </span>

1, 2, 3, 4,

तीन मापदंडों के साथ:

<span ng-repeat="i in range(-2, .7, .5)">{{ i }}, </span>

-2, -1.5, -1, -0.5, 0, 0.5,


6

आप angular.filter मॉड्यूल ( https://github.com/a8m/angular-filter ) में फ़िल्टर करने से पहले 'के बाद' या 'का उपयोग कर सकते हैं

$scope.list = [1,2,3,4,5,6,7,8,9,10]

HTML:

<li ng-repeat="i in list | after:4">
  {{ i }}
</li>

परिणाम: 5, 6, 7, 8, 9, 10


6

अपने नियंत्रक में किसी भी परिवर्तन के बिना, आप इसका उपयोग कर सकते हैं:

ng-repeat="_ in ((_ = []) && (_.length=51) && _) track by $index"

का आनंद लें!


एक दिन से अधिक संघर्ष कर रहा है और अंत में केवल इस वाक्य रचना ने मेरे लिए काम किया है
एगेल अमोडिया

3

सबसे छोटा उत्तर: कोड की 2 लाइनें

JS (आपके AngularJS कंट्रोलर में)

$scope.range = new Array(MAX_REPEATS); // MAX_REPEATS should be the most repetitions you will ever need in a single ng-repeat

एचटीएमएल

<div data-ng-repeat="i in range.slice(0,myCount) track by $index"></div>

... myCountसितारों की संख्या कहां है जो इस स्थान पर दिखाई देनी चाहिए।

आप $indexकिसी भी ट्रैकिंग संचालन के लिए उपयोग कर सकते हैं । उदाहरण के लिए, यदि आप इंडेक्स पर कुछ म्यूटेशन प्रिंट करना चाहते हैं, तो आप निम्नलिखित में डाल सकते हैं div:

{{ ($index + 1) * 0.5 }}

2

अंडरस्कोरजेस का उपयोग करना:

angular.module('myModule')
    .run(['$rootScope', function($rootScope) { $rootScope.range = _.range; }]);

$rootScopeइसे हर जगह उपलब्ध कराने के लिए इसे लागू करना :

<div ng-repeat="x in range(1,10)">
    {{x}}
</div>

2

बहुत सरल एक:

$scope.totalPages = new Array(10);

 <div id="pagination">
    <a ng-repeat="i in totalPages track by $index">
      {{$index+1}}
    </a>   
 </div> 

2

नमस्ते, आप इसे AngularJS (NO Directive की आवश्यकता है) का उपयोग करके शुद्ध HTML का उपयोग करके प्राप्त कर सकते हैं!

<div ng-app="myapp" ng-controller="YourCtrl" ng-init="x=[5];">
  <div ng-if="i>0" ng-repeat="i in x">
    <!-- this content will repeat for 5 times. -->
    <table class="table table-striped">
      <tr ng-repeat="person in people">
         <td>{{ person.first + ' ' + person.last }}</td>
      </tr>
    </table>
    <p ng-init="x.push(i-1)"></p>
  </div>
</div>

1

नियंत्रक में स्कोप सेट करें

var range = [];
for(var i=20;i<=70;i++) {
  range.push(i);
}
$scope.driverAges = range;

Html टेम्पलेट फ़ाइल में रिपीट सेट करें

<select type="text" class="form-control" name="driver_age" id="driver_age">
     <option ng-repeat="age in driverAges" value="{{age}}">{{age}}</option>
</select>

1

@ मोर्मगिल के समाधान में सुधार

app.filter('makeRange', function() {
  return function(inp) {
    var range = [+inp[1] && +inp[0] || 0, +inp[1] || +inp[0]];
    var min = Math.min(range[0], range[1]);
    var max = Math.max(range[0], range[1]);
    var result = [];
    for (var i = min; i <= max; i++) result.push(i);
    if (range[0] > range[1]) result.reverse();
    return result;
  };
});

प्रयोग

<span ng-repeat="n in [3, -3] | makeRange" ng-bind="n"></span>

3 2 1 0 -1 -2 -3

<span ng-repeat="n in [-3, 3] | makeRange" ng-bind="n"></span>

-3 -2 -1 0 1 2 3

<span ng-repeat="n in [3] | makeRange" ng-bind="n"></span>

0 1 2 3

<span ng-repeat="n in [-3] | makeRange" ng-bind="n"></span>

0 -1 -2 -3


1

मैंने निम्नलिखित कोशिश की और यह मेरे लिए ठीक काम किया:

<md-radio-button ng-repeat="position in formInput.arrayOfChoices.slice(0,6)" value="{{position}}">{{position}}</md-radio-button>

कोणीय 1.3.6


1

पार्टी के लिए देर से। लेकिन मैं यह कर रहा था:

आपके नियंत्रक में:

$scope.repeater = function (range) {
    var arr = []; 
    for (var i = 0; i < range; i++) {
        arr.push(i);
    }
    return arr;
}

एचटीएमएल:

<select ng-model="myRange">
    <option>3</option>
    <option>5</option>
</select>

<div ng-repeat="i in repeater(myRange)"></div>

1

यह jzm का सुधरा हुआ उत्तर है (मैं कोई और टिप्पणी नहीं कर सकता / सकती क्योंकि मैं उसके उत्तर पर टिप्पणी करूंगा / क्योंकि उसमें त्रुटियां शामिल हैं)। फ़ंक्शन का प्रारंभ / अंत श्रेणी मान है, इसलिए यह अधिक लचीला है, और ... यह काम करता है। यह विशेष मामला महीने के दिन के लिए है:

$scope.rangeCreator = function (minVal, maxVal) {
    var arr = [];
   for (var i = minVal; i <= maxVal; i++) {
      arr.push(i);
   }
   return arr;
};


<div class="col-sm-1">
    <select ng-model="monthDays">
        <option ng-repeat="day in rangeCreator(1,31)">{{day}}</option>
    </select>
</div>

0

मैंने इसे कोड़ा और देखा कि यह कुछ के लिए उपयोगी हो सकता है। (हाँ, CoffeeScript। मुझे मुकदमा करो।)

आदेश

app.directive 'times', ->
  link: (scope, element, attrs) ->
    repeater = element.html()
    scope.$watch attrs.times, (value) ->
      element.html ''
      return unless value?
      element.html Array(value + 1).join(repeater)

काम में लाना:

एचटीएमएल

<div times="customer.conversations_count">
  <i class="icon-picture></i>
</div>

क्या यह कोई सरल हो सकता है?

मैं फिल्टर के बारे में सावधान हूं क्योंकि कोणीय हर समय बिना किसी अच्छे कारण के उनका पुनर्मूल्यांकन करना पसंद करता है, और यदि आप मेरे जैसे हजारों हैं तो यह बहुत बड़ी अड़चन है।

यह निर्देश आपके मॉडल में परिवर्तन के लिए भी देखेगा, और तदनुसार तत्व को अपडेट करेगा।


यह अच्छा है, लेकिन ngRepeat का कहना है कि यह खुद की स्कूपिंग है। तो आपको प्रत्येक आइटम के लिए संकलन चलाना होगा जो जोड़ा गया है। तुम भी एनिमेशन का अनुकरण करने की आवश्यकता होगी क्योंकि ngRepeat आपके लिए ऐसा करता है।
मत्सको

2
योगदान देने के लिए धन्यवाद, लेकिन यह मानते हुए कि ओपी कॉफ़ीस्क्रिप्ट जानता है, यह क्या है, इसे जेएस में कैसे संकलित किया जाए, या कभी किसी बिल्ड टूल का उपयोग किया है जैसे कि एक बड़ा खिंचाव है। हम सभी यहां सीखने या मदद करने के लिए हैं, इसलिए, अतिरिक्त मील पर जाएं, उस पिल्ला को परिवर्तित करें। (आप पर मुकदमा दायर किया गया है!)
Augie गार्डनर

0
<div ng-init="avatars = [{id : 0}]; flag = true ">
  <div ng-repeat='data in avatars' ng-if="avatars.length < 10 || flag"
       ng-init="avatars.length != 10 ? avatars.push({id : $index+1}) : ''; flag = avatars.length <= 10 ? true : false">
    <img ng-src="http://actual-names.com/wp-content/uploads/2016/01/sanskrit-baby-girl-names-400x275.jpg">
  </div>
</div>

अगर आप html में इसे बिना किसी कंट्रोलर या फैक्ट्री के हासिल करना चाहते हैं।


0

मान लीजिए $scope.refernceurlकि एक सरणी है

for(var i=0; i<$scope.refernceurl.length; i++){
    $scope.urls+=$scope.refernceurl[i].link+",";
}

-8

यह सबसे सरल संस्करण है: पूर्णांक के सरणी का उपयोग करें ...।

 <li ng-repeat="n in [1,2,3,4,5]">test {{n}}</li>


3
यह भयानक है।
टिफ़नी लोव

@Stefan, आपको संभावना है कि डाउनवोट प्राप्त हो सकता है क्योंकि समाधान हार्ड-कोडित संग्रह का उपयोग नहीं कर सकता है।
Tass
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.