在ng-repeat angular中对数组进行随机排序

5

我正在创建一份问答题,每次开始时我希望对问题进行随机排列,以便它们不会每次以相同的顺序出现。

我的HTML代码如下:

<div ng-repeat="question in questions | filter:ids | orderBy:randomSort">
    <div id="question">{{question.question}}</div><img id="nextImg" ng-src="../app/img/next.png" ng-click="next()" />
    <img class="quizImg" ng-hide="{{question.image}}==null" ng-src="{{question.image}}" />

    <div class="answer" ng-repeat="answer in question.answers">
        <input type="radio" ng-click="checked(answer)">{{answer.answer}}
    </div>
    <!--input id="nextQuestion" type="button" ng-click="next()" value="{{buttonText}}"-->
</div>

而这是我的控制器中的代码

 lycheeControllers.controller('quizCtrl', ['$scope', '$http', function ($scope, $http) {
    $http.get('json/questions.json').success(function (data) {
        //all questions
        $scope.questions = data;

        $scope.titel = "Check your knowledge about lychees"


        $scope.randomSort = function(question) {
                      return Math.random();
                    };

        //filter for getting answers / question
        $scope.ids = function (question) {
            return question.id == number;
        }

        $scope.find = function (id) {
            if (id == number) {
                return true;
            }
        }


        $scope.next = function () {
            if (!(number == (data.length))) {
                //questionId++;
                number++;
                if (correct == true) {
                    points++;
                }
                //alert(points);
            } else {
                if (!end) {
                    if (correct == true) {
                        points++;
                        end = true;
                    }
                }

                alert("Quiz finished: your total score is: " + points);
            }
            correct = false;
        }

        $scope.checked = function (answer) {
            //alert(answer.answer);

            if (answer.correct == "yes") {
                correct = true;
            } else {
                correct = false;
            }

            //alert(correct);
        }


    });

}])
;

很遗憾,这根本不起作用。


完全不工作有点含糊。您能更具体地说明,然后发布一个包含足够代码以显示您的问题的最小Plunker吗? - Michal Charemza
你的作用域函数在我的简单案例中运行良好:http://jsfiddle.net/A8Eg2/ 点击Run几次以获得不同的结果。 - MarcinJuraszek
它每次都给我相同的结果... - Warri
随机排序函数需要更好的方法,不难在网络搜索中找到随机排序方法...当然,在这个网站上也有很多。 - charlietfl
3个回答

26

感谢http://bost.ocks.org/mike/shuffle/提供的帮助:使用这个洗牌函数:

它的特点是,输入数组保持绑定状态,因为洗牌不会创建一个新数组,而是在同一引用上进行洗牌。

// -> Fisher–Yates shuffle algorithm
var shuffleArray = function(array) {
  var m = array.length, t, i;

  // While there remain elements to shuffle
  while (m) {
    // Pick a remaining element…
    i = Math.floor(Math.random() * m--);

    // And swap it with the current element.
    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
}

副笔: lodash 的 _.shuffle(array) 也不行,因为它们会创建一个新的数组,从而破坏了绑定(因此洗牌后的数组将不会触发模型变为脏)


要完成一个可行解决方案的答案,应按以下步骤执行:

  • 复制该函数,以便您可以在控制器内部使用它。
  • 在您的 $http 结果回调中调用它:
$http.get('json/questions.json').success(function (data) {
  //all questions
  $scope.questions = data;

  shuffleArray($scope.questions);

  ...
}

2

是的,我使用了lodash _.shuffle()方法来解决这种类型的问题。它很容易使用和非常简单。链接 - mdmostafa

0

我在首页随机展示产品时使用了lodash _.shuffle()。它非常简单易用,像下面这样:

home.component.ts文件中,

products: IProduct[] = [];

  constructor(private productService: ProductService) {}

  ngOnInit(): void {
    this.productService
      .getProducts()
      .subscribe((prodData: IProductsResponse) => {
        this.products = _.shuffle(prodData.products);
        console.log(this.products);
      });
  }

home.component.html 文件中,
<div class="col-md-4 col-sm-6" *ngFor="let product of products let idx = index">
            <div class="card my-2" *ngIf="idx <= 8">
                <img
                  [src]="product.image"
                  alt="{{ product.title }}"
                  width="200px"
                  height="300px"
                  class="card-img-top"
                  style="cursor: pointer"
                  (click)="selectProduct(product._id)"
                />
                <div class="card-header">
                  <div class="card-title">
                    <p>{{ product.title.substr(0, 50) | uppercase }}</p>
                  </div>
                </div>
         </div>
 </div>

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