Подтвердить что ты не робот

Ng-repeat по целочисленному значению

Я пытаюсь использовать ng-repeat на div, который должен содержать звездообразное изображение, каждый пирог в JSON имеет свойство rating от 1-5, и я хочу использовать это значение для исключения 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>

Результат:

pies list

4b9b3361

Ответ 1

Оформить заказ

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

Измените свой 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>

Ответ 2

Я решил это следующим образом: "items" - это ваш массив объектов в области $scope, в зависимости от свойства "рейтинг", вы можете показать звезду, если значение меньше или равно сравнению с свойством "рейтинг".

В этом примере я использую некоторые значки, но для случая изображения это одно и то же.

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

Я нашел лучшее решение, которое полностью решает это требование:

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

Ответ 3

Похоже, что вы выполняете итерацию на pies и что где $index получает свое значение. Вместо ng-repeat="rating in ratings[$index]" вы должны использовать ng-repeat="rating in range(pie.rating)" Таким образом, рейтинг будет соответствовать вашему пирогу при заказе. Затем вы можете полностью удалить петлю в контроллере.

Не могли бы вы предоставить немного больше HTML, чтобы мы могли видеть, откуда приходит $index?

С уважением, Camusensei

EDIT: Вы действительно итерации над 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));
}

Ответ 4

Проблема заключается в том, что ng-repeat работает только с массивами или объектами, поэтому вы не можете указывать итерацию x раз (в то время как x - число)

Решением может быть запись функции в JavaScript:

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

Затем используйте этот html для отображения звезд без $index:

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

Ответ 5

В 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}} &nbsp;&nbsp;</span>
</div>