#javascript #angularjs
#javascript #angularjs
Вопрос:
Я знакомлюсь с AngularJS и собираю простое приложение для случайного рисования. У меня есть четыре кнопки, позволяющие вам «вытянуть» одну или две карты из любой из двух колод (представленных двумя отдельными файлами JSON). В готовом виде мой образец приложения в основном работает, но рандомизация не происходит, если нажать кнопку для отображаемой в данный момент колоды (вы получаете те же точные данные в том же точном порядке)… повторная рандомизация выполняется только в том случае, если вы нажимаете, чтобы взять из другой колоды, а затем возвращаетесь обратно.
Я все еще сбит с толку некоторой «магией» Angular, и я вижу, что фильтр срабатывает при каждом нажатии … Так что я остаюсь ломать голову над этим.
Вот HTML…
<div ng-controller="Cards">
<p>
<button ng-click="whichDeck=franchises;qty=1;shuffle=undefined">DRAW FRANCHISE</button><button ng-click="whichDeck=franchises;qty=2">X2</button>
</p>
<p>
<button ng-click="whichDeck=twists;qty=1">DRAW TWIST</button><button ng-click="whichDeck=twists;qty=2">X2</button>
</p>
<ul class="cards">
<li class="card" ng-repeat="card in whichDeck | shuffle | limitTo:qty"> <!-- filter:query -->
<h2>{{card.Title}}</h2>
<h3 ng-show="card.Origin">{{card.Origin}}</h3>
<p>{{card.Description}}</p>
</li>
</ul>
</div>
Вот JS…
var app = angular.module('myApp',['Shuffle']);
app.controller('Cards', ['$scope', '$http', function($scope, $http) {
var controller = this;
$scope.franchises = [];
$scope.twists = [];
$scope.deck = '';
$http.get('js/franchises.json').success(function(data){
$scope.franchises = data;
});
$http.get('js/twists.json').success(function(data){
$scope.twists = data;
});
}]);
var shuffle = angular.module('Shuffle', []);
shuffle.filter('shuffle', function() {
var shuffledArr = [],
shuffledLength = 0;
return function(arr) {
if (typeof(arr)==='undefined')
arr = [];
var o = arr.slice(0, arr.length);
if (shuffledLength == arr.length) return shuffledArr;
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
shuffledArr = o;
shuffledLength = o.length;
return o;
};
});
Комментарии:
1. Две вещи … во-первых, оказывается, что фильтр shuffle, который я использовал (из другого потока StackOverflow), предназначен для ТОГО, чтобы НЕ обновляться. Причина этого в том, что Angular будет выдавать ошибки дайджеста как сумасшедший, когда вы выполняете такого рода сложную операцию в фильтре (фильтры выполняются ЧАСТО и, следовательно, имеют ограничения). Второе: извлекая перемешивание из фильтра и помещая его в контроллер, вы избегаете проблемы с ошибкой дайджеста и получаете новое перемешивание при каждом нажатии. Спасибо, Мошо!
Ответ №1:
Вот пример того, как этого можно достичь, я думаю, вы слишком все усложняете.
HTML:
<div ng-app="" ng-controller="Ctrl">
<button ng-click="shuffle(obj)">shuffle</button>
<div ng-repeat="o in obj">
{{o}}
</div>
</div>
JS:
function Ctrl($scope) {
$scope.obj = [1,2,3,4,5,6,7,8,9]
//generic shuffling function
$scope.shuffle = function(o){
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
};
ng-repeat
используется порядок массива, и изменения в массиве в области видимости будут автоматически отражены в представлении.