AngularJS orderby не работает при редактировании orderby-свойства
У меня есть список объектов в моей области и я хочу перебрать их, показать некоторые из их свойств в порядке упорядочения по некоторым свойствам и изменить их.
ng-repeat используется для отображения текстовых полей, привязанных к каждому объекту моего списка, и применяется фильтр orderby, который принимает "позицию" в качестве параметра.
Еще раз, позиция также редактируема!
Теперь мы меняем положение определенного объекта один раз (угловая переупорядочивает список, как и ожидалось), а затем меняем дважды. Angular не меняет порядок в списке.
Может ли кто-нибудь объяснить, как можно исправить эту ситуацию "только один раз" и каковы причины такого поведения?
Вот скрипка: JSFiddle
HTML
<div ng-controller="MyCtrl">
<p>List of activities:</p>
<div ng-repeat="activity in model.activities | orderBy: 'position'">
<textarea type="text" ng-model="activity.name">
</textarea>
{{activity.name}}
<input type="text" ng-model="activity.position">
</div>
</div>
JS
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.model = {
activities: [
{name: "activity 1", position: 1},
{name: "activity 2", position: 2},
{name: "activity 3", position: 3},
{name: "activity 4", position: 4},
{name: "activity 5", position: 5}
]
};
}
2 ответа
Здесь это идет.
Почему код ведет себя так?
position
связан с text
вход. Это делает текст целыми числами, а затем переводится в строки, как только вы начинаете печатать. Тогда порядок становится нечетным, и поэтому он терпит неудачу.
Как это исправить?
У вас есть два варианта. Первый вариант - поменять type="text"
от type="number"
тогда это сработает. Если это не вариант, вы можете создать простую директиву (Angular 1.2 и выше)
myApp.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, el, attr, ctrl){
ctrl.$parsers.unshift(function(viewValue){
return parseInt(viewValue, 10);
});
}
};
});
Что этот код делает, так это разбирает каждое значение в целое число, заставляя его работать.
Это произошло потому, что ваш position
Свойство привязано к текстовому значению. Это означает, что значение вашей позиции становится строкой после редактирования через ввод.
Вам необходимо создать собственную сортировку.
Например:
<div ng-repeat="activity in getOrderedData()">
{{activity.name}}
<input type="text" ng-model="activity.position">
</div>
$scope.getOrderedData = function(){
return $scope.model.activities.sort(compare);
};
var compare = function(a,b){
if (parseInt(a.position) < parseInt(b.position))
return -1;
if (parseInt(a.position) > parseInt(b.position))
return 1;
return 0;
};
Это будет работать с каждой версией AngularJS.
Пожалуйста, смотрите этот JSFiddle для всего рабочего примера.
Надеюсь, поможет!