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 для всего рабочего примера.

Надеюсь, поможет!

Другие вопросы по тегам