2015-01-24 6 views
19

Ich versuche ng-repeat auf einem div zu verwenden, die ein Sternbild enthalten sollte, jeder Kuchen in der JSON hat eine rating Eigenschaft von 1-5, und ich möchte diesen Wert verwenden, um aus zu loopen x Anzahl der Sterne. Ich habe das etwas funktioniert, aber es ist fehlerhaft in der Art, dass ich das Array nicht neu sortieren kann und die Sterne dem richtigen Element in der Liste folgen lassen, da ich [$index] verwende, um die Iteration zu verfolgen.Ng-Wiederholung auf Integer-Wert

Meine Lösung ist auch ziemlich hässlich, da ich Arrays mit so vielen Indexplatzhaltern wie der Wert der rating -Eigenschaft erstelle und diese dann in ein Array verschiebe, um die entsprechende Anzahl von Bildern auszulösen. Ich hätte gerne eine elegantere Lösung.

Wie sollte ich über dieses Problem gehen, ohne [$index] zu verwenden?

Snippet des JSON:

{"pies": [ 
    ... 

    { 
     "name": "Blueberry pie", 
     "imageUrl": "img/blueberrypie.png", 
     "id": "1", 
     "rating": "5", //Ng-repeat depending on this value 
     "description": "Blueberry pie is amazing." 
    }, 

    ... 
]} 

Mein 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); 
     }) 
}]); 

Die Liste, die die Torte Elemente enthält:

<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> 

Ergebnis:

pies list

+0

vielleicht http://stackoverflow.com/questions/16824853/way-to-ng-repeat- defined-number-statt-von-repeated-over-array wird helfen – cyan

+0

@cyan sah sich das schon zweimal an, konnte aber nicht herausfinden, wie es in meinem Fall funktioniert. – Chrillewoodz

+0

$ scope.ratings ist in der gleichen Reihenfolge wie json Daten gefüllt? Übrigens, könnten Sie Code in Erfolgsfunktion machen eine andere Funktion für die Code-Reinigung machen? – cyan

Antwort

19

Kasse this

<div ng-app='myApp' ng-controller="Main"> 
    <span ng-repeat="n in range('5')">Start{{$index}} &nbsp;&nbsp;</span> 
</div> 

$scope.range = function(count){ 

    var ratings = []; 

    for (var i = 0; i < count; i++) { 
    ratings.push(i) 
    } 

    return ratings; 
} 

ändern, um Ihre HTML

<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> 
+0

Wie übergebe ich den aktuellen Bewertungswert als Parameter? – Chrillewoodz

+0

hat meine Antwort bearbeitet. Jetzt brauchen Sie kein Rating-Array. Passieren Sie einfach pie.rating zur Bereichsfunktion. Und du bist gut zu gehen. – dhavalcengg

+0

Hmm .. Ich habe ein bisschen seltsam. Wenn ich + zähle, bekomme ich überhaupt keine Sterne, wenn ich zähle, bekomme ich nur einen. Irgendeine Idee warum? Meine Lösung ist identisch mit deiner. – Chrillewoodz

2

folgenden Es sieht aus wie Sie auf dem pies iterieren und das ist, wo die $index von seinem Wert bekommt. Anstelle von ng-repeat="rating in ratings[$index]" sollten Sie ng-repeat="rating in range(pie.rating)" verwenden Auf diese Weise würde die Bewertung Ihren Kuchen bei der Bestellung folgen. Dann könnten Sie die Schleife im Controller vollständig entfernen.

Konnten Sie nur ein wenig mehr HTML zur Verfügung stellen, damit wir sehen konnten, woher die $index stammt?

Grüße, Camusensei

EDIT: Sie sind in der Tat so über pies.pies in ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp" , was ich schrieb früher funktionieren sollte laufen. Siehe unten für umfassende Änderungen.

-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, habe ich vergessen, die Range-Funktion (von Ariya Hidayat inspiriert):

$scope.range = function(count){ 
    return Array.apply(0, Array(+count)); 
} 
+0

Ich habe die Frage aktualisiert. – Chrillewoodz

+0

Sehen Sie sich meinen Kommentar in der obigen Antwort an. – Chrillewoodz

+0

Verwenden Sie für Debugzwecke diese Bereichsfunktion: '$ scope.range = function (count) {var a = neues Array (+ count); console.log (Anzahl, a); return a;}; ' – Camusensei

1

Die probl em ist, dass ng-repeat nur mit Arrays oder Objekten arbeitet, so kann man nicht wiederholen x mal sagen (während x eine Zahl)

Eine Lösung könnte sein, eine Funktion in JavaScript zu schreiben:

$scope.getNumber = function(num) { 
    return (new Array(num)); 
} 

Ein verwenden Sie diesen hTML dann ohne $ index, die Sterne zu zeigen:

<div ng-repeat="rating in getNumber(pie.rating)"></div> 
0

In Angular 1.4+ Sie die folgende Fehlermeldung erhalten, wenn ein leeres Array mit:

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed.

Die folgenden Werke:

$scope.range = function(count) { 
    return Array.apply(0, Array(+count)).map(function(value,index){ 
     return index; 
    }); 
} 

<div ng-app='myApp' ng-controller="Main"> 
    <span ng-repeat="n in range(5)">Start{{$index}} &nbsp;&nbsp;</span> 
</div> 
3

ich das auf diese Weise gelöst: „Artikel“ ist Ihr Array von Objekten in dem $ Umfang, die Eigenschaft „Bewertung“ accesing, können Sie den Stern, wenn der Wert zeigen ist weniger oder das gleiche im Vergleich zu der "Rating" -Eigenschaft.

In diesem Beispiel verwende ich einige Symbolschriften, aber für den Fall eines Bildes ist das gleiche.

<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> 

Ich habe eine bessere Lösung gefunden, die überhaupt diese Anforderung löst:

https://github.com/fraserxu/ionic-rating