Forgular için Açısal JS sonu


256

Bir açısal foreach döngü var ve bir değer eşleşirse döngü kırmak istiyorum. Aşağıdaki kod çalışmıyor.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    break;
  }
});

Bunu nasıl alabilirim?


1
Neden bir döngüye girmek yerine sadece değeri bulamadığınızı anlamıyorum. Belki verdiğiniz örnek tüm hikayeyi anlatmaz, ama @Aman'ın aşağıda söylediklerini yapmayı tercih ederim. Neden aşağıda belirtildiği gibi döngüye girip bazı () her seferinde bunu daha zarif bir şekilde yaptığında bir kontrol gerçekleştirin. Javascript'i işlevsel bir dil olarak ele alırsanız, bunları kontrol ederken / while / break tipi kontroller için kullanmanın bir anlamı olmaması gerektiğini unutmayın. Bu nedenle, foreach, find, some, etc.
Adrian Rodriguez

Yanıtlar:


265

Bunu yapmanın bir yolu yok. Bkz. Https://github.com/angular/angular.js/issues/263 . Ne yaptığınıza bağlı olarak, sadece döngü gövdesine girmemek için bir boole kullanabilirsiniz. Gibi bir şey:

var keepGoing = true;
angular.forEach([0,1,2], function(count){
  if(keepGoing) {
    if(count == 1){
      keepGoing = false;
    }
  }
});

45
Ben sadece !keepGoing && return;fonksiyonun üstüne, daha az kod eklemek istiyorum .
Andrew Joslin

46
Bu en iyi uygulamalar değil, burada açısal forEach döngüsü asla kırılmaz ve açısal kırmak için hiçbir şey yoktur. ForEach. Yerel için döngü açısaldan yaklaşık% 90 daha hızlıdır. Bu nedenle, koşul eşleşmesini kırmak istediğinizde yerel için döngü kullanmak daha iyidir. Teşekkürler
Nishchit Dhanani

xcatly nerede sıkışmış ... ve bu yardımcı oldu ... bir ton teşekkürler ... Her neyse, forEach döngü kırılmaz yapmak için nedenini bilmek istiyorum. Varsa
Saurabh Tiwari

ForEach döngüsünü bozmaması için bu kabul edilen cevap olmamalıdır. Sadece döngü içindeki tüm mantığı yürütmemenin bir yoludur.
Nebulosar

296

angular.forEachDöngü bir koşul maç kesemez.

Kişisel tavsiyem bunun yerine bir NATIVE FOR döngüsü kullanmaktır angular.forEach.

NATIVE FOR döngüsü, döngüler için diğerinden yaklaşık % 90 daha hızlıdır.

Döngü kopması için, döngü testi sonucu için

ANGULAR'DA loop İÇİN KULLANIN:

var numbers = [0, 1, 2, 3, 4, 5];

for (var i = 0, len = numbers.length; i < len; i++) {
  if (numbers[i] === 1) {
    console.log('Loop is going to break.'); 
    break;
  }
  console.log('Loop will continue.');
}

1
Bu benim için işe yaramıyor. Tek yaptığı, döngünün bu özel yinelemesini bitirmek. Ama sonra bir sonraki yinelemeye geçer.
Ben

1
@Ben, Üzgünüm ben, Bu benim hatamdı ama şimdi uzun araştırmalardan sonra cevabımı güncelliyorum. Umarım bu sana yardımcı olmuştur . Teşekkür ederim
Nishchit Dhanani

1
@LGama: - Davan nedir?
Nishchit Dhanani

3
jsperf.com/angular-foreach-performance hangi işlevi seçmeniz gerektiğine karar vermek için kendi tarayıcınızda test edin. IE11 üzerinde test yaptım ve ekran görüntüsünde olduğu kadar hızlı. Ayrıca Array.some () test edildi ama IE11 üzerinde Array.forEach () daha yavaş ama daha hızlı olabilir angular.foreach ;-). Veya burada test edin jsperf.com/angular-foreach-vs-native (tüm krediler orijinal yazara gider, bana değil ;-))
Sebastian

6
JSperf ile bile "yerli için% 90 daha hızlı" diyemezsiniz. Senaryonuzda bu, iç fonksiyonun yürütülmesinin ne kadar pahalı olduğuna ve döngüden (break) erken çıkarak kaç yürütmenin kaydedilebileceğine bağlıdır.
hgoebl

22

lütfen ForEach'ın bazı veya her örneğini kullanın,

Array.prototype.some:
some is much the same as forEach but it break when the callback returns true

Array.prototype.every:
every is almost identical to some except it's expecting false to break the loop.

Bazıları için örnek:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.some(function (value, index, _ary) {
    console.log(index + ": " + value);
    return value === "JavaScript";
});

Her biri için örnek:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.every(function(value, index, _ary) {
    console.log(index + ": " + value);
    return value.indexOf("Script") > -1;
});

Daha fazla bilgi için
http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/


no @ AngelS.Moreno, herkes eldeki durum için özel olarak tasarlanmış bir yöntem yerine yerel bir değişken kullanmayı tercih ediyor
Oded Niv

18

Dizi Bazı Yöntemini Kullanma

 var exists = [0,1,2].some(function(count){
      return count == 1
 });

exist doğru döndürür ve bunu işlevinizde bir değişken olarak kullanabilirsiniz

if(exists){
    console.log('this is true!')
}

Dizi Bazı Yöntem - Javascript


4
Benim için kullanımına tek sebebi angular.forEach()ben yok IE8, desteklemek zorunda olmasıdır Array.forEach()... ya Array.some().
Bennett McElwee

2
Array.forEach'ı kolayca çoklu doldurabilirsiniz. Sayfanın altına bakın: developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
zumalifeguard

6

Bildiğim kadarıyla, Angular böyle bir işlev sağlamıyor. Alt çizgileri kullanmak isteyebilirsinizfind() çizginin işlevini (temel olarak işlev doğru döndükten sonra döngüden kopan bir forEach).

http://underscorejs.org/#find


bu, yanal olarak sorunu çözebilir, ancak tapu döngüyü bozmaz.
Elise Chant

Veya döngü için yerli
shanti

6

AngularJS ile birlikte jQuery (dolayısıyla jqLite değil) kullanırsanız, boolean dönüş değeri ifadesine dayalı olarak kesme ve devam etmeyi sağlayan $ .each ile yineleme yapabilirsiniz.

JSFiddle:

http://jsfiddle.net/JEcD2/1/

JavaScript:

var array = ['foo', 'bar', 'yay'];
$.each(array, function(index, element){
    if (element === 'foo') {
        return true; // continue
    }
    console.log(this);
    if (element === 'bar') {
        return false; // break
    }
});

Not:

JQuery kullanımı kötü olmasa da, yerel Array.some veya Array.every işlevlerini, yerel forEach belgelerinde okuyabileceğiniz gibi MDN tarafından önerilir :

"Bir forEach döngüsünü durdurmanın veya kırmanın bir yolu yoktur. Çözüm Array.every veya Array.some kullanmaktır"

MDN tarafından aşağıdaki örnekler verilmektedir:

Array.some:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed is false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed is true

Array.every:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true

6

Somut olarak, bir forEachdöngüden çıkabilir ve herhangi bir yerden bir istisna atabilirsiniz.

try {
   angular.forEach([1,2,3], function(num) {
      if (num === 2) throw Error();
   });
} catch(e) {
    // anything
}

Bununla birlikte, başka bir kitaplık kullanıyorsanız veya kendi işlevinizi, findbu durumda bir işlevi uygulamanız daha iyidir , bu nedenle kodunuz en üst düzeydedir.


10
Soruya cevap verdin! Umarım kimse bunu yapmaz :)
Jason Cox

Gereksiz yere bir istisna atmak, durumu ele almanın iyi bir yolu değildir. @ Dnc253 tarafından sağlanan çözümü kontrol edin. Stackoverflow.com/a/13844508/698127
Aamol

4

Bunu mola olarak deneyin;

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return true;
  }
});

3

Diğer cevapların belirttiği gibi, Angular bu işlevi sağlamaz. jQuery bunu yapar ve jQuery'yi Angular'ın yanı sıra yüklediyseniz,

jQuery.each ( array, function ( index, value) {
    if(condition) return false; // this will cause a break in the iteration
})

Bkz. Http://api.jquery.com/jquery.each/


2
OP bir AngularJS çözümü istedi, doğru cevap HAYIR :)
Shannon Hochkins

3

Normalde javascript içinde bir "her" döngü kırmak için bir yolu yoktur. Genelde yapılabilecekler “kısa devre” yöntemini kullanmaktır.

    array.forEach(function(item) {
      // if the condition is not met, move on to the next round of iteration.
      if (!condition) return;

      // if the condition is met, do your logic here
      console.log('do stuff.')
    }


2

break her açısal forEach içinde elde etmek mümkün değil, bunu yapmak için forEach'ı değiştirmemiz gerekiyor.

$scope.myuser = [{name: "Ravi"}, {name: "Bhushan"}, {name: "Thakur"}];  
                angular.forEach($scope.myuser, function(name){
                  if(name == "Bhushan") {
                    alert(name);
                    return forEach.break(); 
                    //break() is a function that returns an immutable object,e.g. an empty string
                  }
                });

Bu cevap tam görünmüyor. Lütfen tanımlanması gerekip gerekmediğini break()veya zaten açısal bir parçası olup olmadığını belirtin. Lütfen değilse tanımlayın.
jeoidesic

2

Bunu kullanabilirsiniz:

var count = 0;
var arr = [0,1,2];
for(var i in arr){
   if(count == 1) break;
   //console.log(arr[i]);
}

1
var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];
var keepGoing = true;
ary.forEach(function(value, index, _ary) {
    console.log(index)
    keepGoing = true;
    ary.forEach(function(value, index, _ary) {
        if(keepGoing){ 
            if(index==2){
                keepGoing=false;
            }
            else{
                console.log(value)
            }

        }      
    });
});

0
$scope.arr = [0, 1, 2];  
$scope.dict = {}
for ( var i=0; i < $scope.arr.length; i++ ) {
    if ( $scope.arr[i] == 1 ) {
        $scope.exists = 'yes, 1 exists';
        break;
    }
 }
 if ( $scope.exists ) {
     angular.forEach ( $scope.arr, function ( value, index ) {
                      $scope.dict[index] = value;
     });
 }

0

Bunu dönüşle yapmayı tercih ederim. Döngü parçasını özel işleve koyun ve döngüyü kırmak istediğinizde geri dönün.


0

Bu eski, ama bir dizi filtre gerekeni yapabilir farkında:

var arr = [0, 1, 2].filter(function (count) {
    return count < 1;
});

Daha sonra arr.forEachve diğer dizi işlevlerini çalıştırabilirsiniz .

Döngü işlemlerini tamamen kısmak istiyorsanız, bunun muhtemelen istediğinizi yapmayacağını anlıyorum. Bunun için en iyi şekilde kullanın while.


0

Bu örnek işe yarar. Dene.

var array = [0,1,2];
for( var i = 0, ii = array.length; i < ii; i++){
  if(i === 1){
   break;
  }
}

1
Sanırım bir fordöngü istemiyor , kullanım durumunun muhtemelen foreachdeğilfor
Hassen Ch.

0

Döngüyü kırmak için Return tuşunu kullanın.

angular.forEach([0,1,2], function(count){
  if(count == 1) {
    return;
  }
});

0
onSelectionChanged(event) {
    let selectdata = event['api']['immutableService']['gridOptionsWrapper']['gridOptions']['rowData'];
    let selected_flag = 0;

    selectdata.forEach(data => {
      if (data.selected == true) {
        selected_flag = 1;
      }
    });

    if (selected_flag == 1) {
      this.showForms = true;
    } else {
      this.showForms = false;
    }
}

-1

Bunun returnyerine kullanırdım break.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return;
  }
});

Tıkır tıkır çalışıyor.


bu geçerli bir çözüm değil. look: function test () {angular.forEach ([1,2,3,4,5,6,7,8,9], işlev (değer, dizin) {if (value == 2) return; console.log (değer);})} çıktı:> teste (); 1 3 4 5 6 7 8 9
otaviodecampos

-2

Sadece $ index ekleyin ve aşağıdakileri yapın:

angular.forEach([0,1,2], function(count, $index) {
     if($index !== 1) {
          // do stuff
     }
}

OP döngüden çıkmak istiyor.
Angel S. Moreno
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.