div
でng-repeat
を使用しようとしていますが、これにはスター画像が含まれている必要があり、JSONの各パイには1〜5のrating
プロパティがあります。この値はx個の星をループアウトします。私はこれをいくらか動作させましたが、[$index]
を使用して反復を追跡しているため、配列を再ソートして星をリスト内の正しいアイテムに追従させることができないという点で欠陥があります。
rating
プロパティの値と同じ数のインデックスプレースホルダーを持つ配列を作成し、これを配列にプッシュして適切な数の画像をループアウトするため、私のソリューションもかなりいです。もっとエレガントなソリューションが欲しいです。
[$index]
を使用せずにこの問題を解決するにはどうすればよいですか?
JSONのスニペット:
{"pies": [
...
{
"name": "Blueberry pie",
"imageUrl": "img/blueberrypie.png",
"id": "1",
"rating": "5", //Ng-repeat depending on this value
"description": "Blueberry pie is amazing."
},
...
]}
私のコントローラー:
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);
})
}]);
パイアイテムを含むリスト:
<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>
結果:
チェックアウト this
<div ng-app='myApp' ng-controller="Main">
<span ng-repeat="n in range('5')">Start{{$index}} </span>
</div>
$scope.range = function(count){
var ratings = [];
for (var i = 0; i < count; i++) {
ratings.Push(i)
}
return ratings;
}
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>
私はこの方法でこれを解決しました:「items」は$ scopeのオブジェクトの配列であり、「rating」プロパティにアクセスします。値が「rating」プロパティと比較して小さいか同じ場合は星を表示できます。
この例では、いくつかのアイコンフォントを使用していますが、画像の場合も同じです。
<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>
私はこの要件をまったく解決するより良いソリューションを見つけました:
pies
を繰り返し処理しているように見えますが、そこから$index
が値を取得します。 ng-repeat="rating in ratings[$index]"
の代わりにng-repeat="rating in range(pie.rating)"
を使用する必要があります。この方法では、注文時に評価が円になります。その後、コントローラーのループを完全に削除できます。
$index
の由来を確認できるように、もう少しHTMLを提供していただけますか?
よろしく、カムセンセイ
編集:pies.pies
のng-repeat="pie in pies.pies | filter:query | orderBy:orderProp"
を繰り返し処理しているので、前に書いたものが機能するはずです。完全な変更については、以下を参照してください。
コントローラー:
$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:申し訳ありませんが、範囲関数を忘れました( Ariya Hidayat からインスピレーションを受けました):
$scope.range = function(count){
return Array.apply(0, Array(+count));
}
問題はそれです ng-repeat
は配列またはオブジェクトでのみ機能するため、x回反復することはできません(xは数値です)
解決策は、JavaScriptで関数を作成することです。
$scope.getNumber = function(num) {
return (new Array(num));
}
次に、このhtmlを使用して、$ indexなしで星を表示します。
<div ng-repeat="rating in getNumber(pie.rating)"></div>
Angular 1.4+では、空の配列を使用すると次のエラーが発生します。
エラー:[ngRepeat:dupes]リピーターでの重複は許可されていません。
以下の作品:
$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}} </span>
</div>