【问题标题】:Ng-repeat on integer valueNg-重复整数值
【发布时间】:2015-03-23 09:37:38
【问题描述】:

我正在尝试在应包含星形图像的 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>

结果:

【问题讨论】:

  • @cyan 已经看了两次,但不知道如何让它在我的情况下工作。
  • $scope.ratings 和 json 数据的填写顺序是一样的吗?对了,能不能把success函数里的代码再做一个代码清洗函数?
  • 据我了解,您尝试列出一些数据,而每个数据元素的星级评分从 1 到 5。对吗?
  • 是的,看看我添加的图像。

标签: javascript html angularjs ng-repeat


【解决方案1】:

我以这种方式解决了这个问题: “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>

我找到了一个更好的解决方案,可以完全解决这个要求:

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

【讨论】:

    【解决方案2】:

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

    将您的 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>
    

    【讨论】:

    • 我如何将当前评级值作为参数传递?
    • 编辑了我的答案。现在您不需要评级数组。只需将 pie.rating 传递给 range 函数。你很高兴。
    • 嗯.. 我有点奇怪。当使用 +count 时,我根本没有得到星星,如果我使用 count,我只会得到一颗。知道为什么吗?我的解决方案和你的一样。
    • 使用其他变量然后在 ng-repeat 中评分。更新了我的答案。
    • 如果您的 pie.rating 为空字符串,可能会发生这种情况。你能再检查一下pie.rating吗?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      看起来您正在对pies 进行迭代,而这正是$index 的价值所在。 而不是ng-repeat="rating in ratings[$index]" 你应该使用ng-repeat="rating in range(pie.rating)" 这样,在订购时评分将跟随您的馅饼。 然后你就可以完全移除控制器中的循环了。

      您能否提供更多的 HTML,以便我们可以看到 $index 的来源?

      问候, 卡缪森

      编辑: 你确实在迭代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));
      }
      

      【讨论】:

      • 看我在上面答案中的评论。
      • 出于调试目的,请使用此范围函数:$scope.range = function(count){var a = new Array(+count); console.log(count, a); return a;};
      • 我们解决了,但仍然不知道是什么原因导致它出现故障。我会进一步调查此事。
      • 好的,我发现问题出在哪里了:2ality.com/2012/06/dense-arrays.html 数组是稀疏的而不是密集的
      • 很有趣,但我尝试了该解决方案,但也没有用。感觉好像有其他东西导致了故障。至少我找到了一个现在可以使用的解决方案;S
      【解决方案5】:

      问题在于ng-repeat 仅适用于数组或对象,因此不能说迭代 x 次(而 x 是一个数字)

      一种解决方案是用 JavaScript 编写一个函数:

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

      然后使用这个 html 来显示没有 $index 的星星:

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

      【讨论】:

        猜你喜欢
        • 2015-04-23
        • 2019-05-13
        • 1970-01-01
        • 2013-12-31
        • 2020-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多