В настоящее время я работаю над приложением на Angular. Пока что все идет хорошо. Я действительно, действительно новичок в angular и удивлен, что это заняло так много времени для первого настоящего блокпоста.
Ситуация:
У меня есть массив объектов, каждый из которых имеет порядок.
category.items = [{id: 1, order: 1, type: {}, ...}, {id: 54, order: 2, type: {}, ...}, {id: 3, order: 3, type: {}, ...}]
Пользователь должен иметь возможность переставить эти элементы. Новый порядок должен быть установлен в свойство объекта 'порядок'.
В HTML эти объекты отображаются так:
<div class="category">
<div class="item" ng-repeat="(itemIndex, item) in category.items track by $index">
<div class="header">
</div>
</div>
</div>
В header-div у меня есть поле ввода, введите select.
<select ng-model="item.order" ng-change="changeItemOrder((itemIndex + 1), item.order, itemIndex)">
<option ng-repeat="item in category.items" ng-value="($index + 1)">{{$index + 1}}</option>
</select>
Код для changeItemOrder:
$scope.changeItemOrder = function(old_order, new_order, item_index) {
new_order = parseInt(new_order);
if (old_order != new_order) {
var upper = Math.max(old_order, new_order);
var lower = Math.min(old_order, new_order);
angular.forEach($scope.category.items, function(item, key) {
if (item_index != key) {
if (new_order < old_order) {
if (item_index >= new_order && (key + 1) >= lower && (key + 1) <= upper) {
item.order = (parseInt(item.order) + 1);
}
} else if (new_order > old_order) {
if (item_index <= old_order && (key + 1) <= upper && (key + 1) >= lower) {
item.order = (parseInt(item.order) - 1);
}
}
} else {
item.order = parseInt(new_order);
}
});
$scope.reorderItems();
}
};
(ReorderItems просто вызывает угловую сортировку с механизмом сортировки по умолчанию, сравнивающим заказы и возвращающим -1, 1 или 0.)
Вот где я обнаружил/заметил/определил одну из самых серьезных ошибок в одном из возможных решений этой проблемы. Здесь я заметил, что мой INT как-то конвертируется в строку, так как при рендеринге в выпадающий список добавляется опция со значением 'string: 2'.
Я пробовал ng-options всеми возможными способами, но даже они приводили к проблемам. Я сделал ng-options, используя item.order как item.order в... и так далее, что просто заставляло порядок переключаться, пока все элементы не имели одинаковый порядок. Попытка использования различных методов группировки или trackbys привела к различным ошибкам, например, внезапное введение NaN en NULL в раскрывающемся списке или полное удаление свойства порядка в целом из объекта-объекта.
До сих пор наименее подверженным ошибкам решением было использование ng-repeat в моих опциях. Это приводит только к несоответствию типа item.order.
Теперь, после долгих поисков, потратив часы на стекопоток (особенно перед тем, как написать этот вопрос с помощью этой изящной мелочи в поиске вопросов), я пришел к вам.
- Как я могу остановить/обойти поведение, когда мой item.order переключен с INT на STRING?
- Если это невозможно, как заставить $ index быть строкой, чтобы модель (строка) соответствовала значению (строке)
-
Если это невозможно, как я могу написать свои ng-параметры, чтобы получить желаемое поведение? (Я серьезно пробовал много, от отслеживания до разных, как и для заявлений, все привело к различным ошибкам)
При начальной загрузке все селекторы показывают правильное выбранное значение, поэтому все item.order изначально INT (я получаю их из нашего API), только после взаимодействия все, кроме объекта, который вызвал переупорядочение, испортились.