在ng-Repeat中随机排列一个数组

3

我有一个对象数组,我使用ng-repeat迭代它。然而,每个对象都有两个属性 - 一个国家(字符串)和城市(数组)。如何在某个按钮单击或页面刷新时随机化这个城市数组。一个例子:

$scope.package = [{
  country: 'Sweden',
  cities: ['aaa', 'bbb']
}, {
  country: 'Sudan',
  cities: ['yyy', 'zzz']
}]

$scope.showNext = function() {
  // shows next slide but randomize the cities
}

<ul>
  <li ng-repeat="pack in package">
    <p>{{pack.country}}</p>
      <span>{{pack.cities}}</span> <!-- cities should be random value from the array -->
  </li>
</ul>
<button ng-click="showNext()"> Next Country </button>

注意:按钮不需要进行随机操作,按钮只是跳转到下一个国家幻灯片,但城市名称应该每次都被打乱。


每次显示城市时,是否意味着应该以不同的顺序显示(例如:aaa,bbb,ccc或bbb,ccc,aaa或aaa,ccc,bbb等)? - Mansi Parekh
由于cities是一个数组,我不能在HTML中放置pack.cities[0],因为这样做将始终是数组中的第一个城市。因此,我希望[ ]内的值是随机的(这里是0或1,因为只有两个元素)。 - Jamie
2个回答

2
你可以使用随机函数来生成随机数据,使用limitTo函数只获取一个随机城市。
更新: 我已经更新了代码片段,不再从页面中调用随机函数(这将在每次刷新页面时都调用函数),而是在页面加载和点击下一页按钮时调用它。

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
  $scope.random = function() {
    return Math.random();
  }
  $scope.package = [{
    country: 'Sweden',
    cities: ['aaa', 'bbb', 'ccc']
  }, {
    country: 'Sudan',
    cities: ['xxx', 'yyy', 'zzz']
  }]

  function generateRandom() {
    angular.forEach($scope.package, function(country) {
      country.random = country.cities[Math.floor(Math.random() * country.cities.length)];
    })
  }
  $scope.showNext = function() {
    generateRandom();
    // shows next slide but randomize the cities
  }
  generateRandom();

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
  <div ng-controller="MyCtrl">
    <ul>
      <li ng-repeat="pack in package">
        <p>{{pack.country}}</p>
        <span>{{pack.random}}</span>
        <!-- <span>{{pack.cities|orderBy:random|limitTo:1}}</span> -->
        <!-- cities should be random value from the array -->
      </li>
    </ul>
    <button ng-click="showNext()"> Next Country </button>
  </div>
</div>


有时候,你的代码会出错:"message": "Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.23/$rootSco... - Mistalis
这个错误似乎在所有情况下都会发生。应用程序仍然可以正常工作,但是我很担心会看到无限循环错误 :) - Jamie
感谢Manshi的答案。今天学到了 limitTo :)) - Jamie
嗨,我已经更新了代码片段,请检查。现在你不会再遇到任何错误了。在Mistalis的代码中,如果你将“显示控制台”设置为true,那么它将会出错。 - Mansi Parekh

2
你可以使用 randomize() 函数在 cities 中随机选择一个 city
<ul>
  <li ng-repeat="pack in package">
    <p>{{pack.country}}</p>
    <span>{{randomize(pack)}}</span> 
  </li>
</ul>

您可以尝试以下代码片段:

function MyCtrl($scope) {
    $scope.package = [
        {country: 'Sweden', cities: ['aaa', 'bbb']}, 
        {country: 'Sudan', cities: ['yyy', 'zzz']}
    ];

    $scope.randomize = function(country) {
        return country.cities[Math.floor(Math.random() * country.cities.length)];
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app ng-controller="MyCtrl">
  <ul>
    <li ng-repeat="pack in package">
      <p>{{pack.country}}</p>
      <span>{{randomize(pack)}}</span> 
    </li>
  </ul>
</div>


嗨,谢谢回答。我尝试了<span>{{city in pack.cities | orderBy: randomize}}</span>但是它给出了一个带有'in'语法错误的提示。 - Jamie
1
谢谢。这绝对是正确的做法 :)) - Jamie
我遇到了一个小问题,因为我正在异步获取这些包并且城市实际上是图像<img ng-src="{{ }}">,所以{{ }}中的值没有被计算。尝试将随机函数放在承诺内部,但没有什么变化。 - Jamie
建议: randomize 可以将显示的城市保存在作用域中 ($scope.country.displayed = country.cities[Math.floor(Math.random() * country.cities.length)];)。在承诺的 .then 结果中为每个国家调用它。 - Mistalis
如果将“显示控制台”设置为true,则有时会出现摘要错误。 - Mansi Parekh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接