Javascript 如何创建无无限摘要循环的随机/随机过滤器

Javascript 如何创建无无限摘要循环的随机/随机过滤器,javascript,angularjs,angularjs-filter,Javascript,Angularjs,Angularjs Filter,我希望实现以下目标: 能够以随机顺序显示阵列中的图像 为了解决这个问题,我决定创建一个过滤器: var app = angular.module('app'); app. filter('randomizer', randomizer); function randomizer() { return function (collection, defaultValue) { var result = defaultValue;

我希望实现以下目标:

  • 能够以随机顺序显示阵列中的图像
为了解决这个问题,我决定创建一个过滤器:

var app = angular.module('app');
app. filter('randomizer', randomizer);


 function randomizer() {

        return function (collection, defaultValue) {

            var result = defaultValue;

            if (!!collection) {
                if (Array.isArray(collection) && collection.length === 1) {
                    result = collection[0] || defaultValue;
                } else if (!Array.isArray(collection)) {
                    result = collection || defaultValue;
                } else {
                    // randomize here please
                    var idx = parseInt(((Math.random()) * collection.length));
                    result = collection[idx] || defaultValue;
                }
            }

            return result;
        }
    }
现在,在template中,我的电话是:

<div class="masonry-pin masonry-brick" ng-repeat="p in vm.list | orderBy: 'updatedAt':true">

     <img ng-src="{{vm.baseUrl + 'documents/view/' + ( p.documents | randomizer:{id: 'notfound'}:p.id).id }}">

</div>
在这里,我甚至没有返回不同的值。。。(如果我同意这里解释的逻辑-)

即使它不是过滤器,也会导致此问题

现在我已经创建了一个服务函数,我遇到了这个问题

 <img ng-src="{{vm.baseUrl + 'documents/view/' + vm.random( p.documents , {id: 'notfound'}).id }}">


vm.random = function (a, s) {

            return utility.randomizer(a, s);
        };

vm.random=函数(a,s){
返回实用程序。随机化器(a,s);
};

那么解决方案是什么呢?

要修复无限摘要,您需要将过滤器包装在
memoize
函数中。解决问题的最佳方法是从
npm
安装
knuth shuffle
lodash
,然后使用您喜欢的任何模块系统创建过滤器。此示例使用CommonJS/browserify

var memoize = require('lodash/function/memoize');
var shuffle = require('knuth-shuffle');

app.filter('shuffle', function() {
  return memoize(shuffle);
});
以这种方式创建筛选器时,如果将空值传递给
shuffle
函数,则可能会出现问题。在这种情况下,只需添加一个检查:

app.filter('shuffle', function() {
  return memoize(function(input) {
    if (input === undefined) { return; }
    return shuffle.apply(null, arguments);
  });
});
您可以从中了解有关无限摘要问题的更多信息

要重新洗牌列表,可以将任意$scope属性传递给筛选器,然后在需要重新洗牌时更改该属性。增加一个数字或使用
Math.random()
都是一种很好的方法。这是因为结果是根据传递的参数进行缓存的,所以传递一个本来无用的参数会产生一个新的结果

myList | shuffle:whatever

您正在直接玩
集合
,它是作用域变量,
集合
触发摘要周期中的任何更改&显然过滤器被触发..这导致
10$digest()迭代次数已达到
此问题。.我建议您先使用
angular复制一份
集合
。复制
&播放它,然后在您使用doneThanks@pankajparkar时分配回结果,但我没有做任何修改。此外,我还更新了我的问题,因为我也在使用ngrepeat语句;并按建议使用副本。但是结果是一样的。可能是重复的,非常感谢,现在我明白了绑定的反应。我仍然想知道为什么逻辑是用ng编写的,它会多次检查一个对象的值,尤其是当它没有变化时。一定有办法告诉他不要看什么的。顺便说一句,u.memoize已经解决了这个问题。我接受了这个答案,因为它解决了我报告的错误。无论如何,我不能随机化,因为它是缓存的。我可以在加载时更改,也可以使用memoizedFunc.cache清除@基于代码的哦,我忘了提那件事了!您应该能够传递任意$scope属性,并在需要重新筛选时对其进行更改。我更新了我的答案来证明这一点。啊哈!再次感谢你。
myList | shuffle:whatever
$scope.whatever = 0;
$scope.reshuffle = function() {
  ++$scope.whatever;
  // OR
  $scope.whatever = Math.random();
};