Как создать обратный вызов для ng-repeat orderBy?

Ищете способ заставить фильтр AngularJS'a ng-repeat orderBy выполнять обратный вызов после завершения рендеринга...

Разметка:

    <div ng-controller="MyCtrl">
    <table>
        <thead>
            <tr>
                <th ng-click="sort('name')">Name:</th>
                <th ng-click="sort('age')">Age:</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in items | orderBy:sortColumn:reverseSort">
                <td>{{item.name}}</td>
                <td>{{item.age}}</td>
            </tr>
        </tbody>
    </table>
</div>

JS:

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
    $scope.items = [{
        "name": "John",
            "age": 25
    }, {
        "name": "Amy",
            "age": 75
    }, {
        "name": "Sarah",
            "age": 12
    }, {
        "name": "Matt",
            "age": 55
    }, {
        "name": "Xaviour",
            "age": 2
    }];

    $scope.sortColumn = 'name';
    $scope.reverseSort = false;

    $scope.sort = function (column) {
        $scope.sortColumn = column;
        $scope.reverseSort = !$scope.reverseSort;
    };

    $scope.sortRenderFinished = function(){
        console.log('Done Rendering!');
        //Do something
    };
}

JSfiddle

Как вы можете видеть. Я хотел бы, чтобы что-то вроде $scope.sortRenderFinished() срабатывало, когда фильтр orderBy завершает выполнение и изменяет порядок строк таблицы.

Любая помощь приветствуется! :-)


person RavenHursT    schedule 21.01.2014    source источник
comment
См.: stackoverflow.com/questions/13471129/   -  person tymeJV    schedule 22.01.2014
comment
Arg... работает для начального рендеринга таблицы с помощью ngRepeat... но не для последующего рендеринга таблицы с помощью orderBy... ссылка   -  person RavenHursT    schedule 22.01.2014
comment
Я не знаком с orderBy, но в этом случае может быть проще создать собственную функцию сортировки для вызова объекта с обратным вызовом для предоставления требуемой функциональности.   -  person caffeinated.tech    schedule 22.01.2014
comment
Думал об этом... но это просто даст мне возможность что-то сделать после того, как массив будет отсортирован... но это не гарантирует, что представление, построенное на данных в этом массиве, уже завершило рендеринг... верно? Очевидно, что, основываясь на ссылке, которую дал @tymeJV, у нас есть способ запустить событие после завершения первоначального рендеринга ng-repeat ... должен быть способ сделать это впоследствии при изменении ссылочного массива.   -  person RavenHursT    schedule 22.01.2014
comment
Хорошо .. @LcLk просто может быть что-то здесь .. может быть, я могу просто написать свою собственную функцию сортировки (поскольку фильтр orderBy, похоже, на самом деле не сортирует массив в родительской области .. grrr), а затем поместите $watch на этом массиве, чтобы сделать то, что мне нужно сделать, как только он будет отсортирован... Попробую!   -  person RavenHursT    schedule 22.01.2014


Ответы (1)


Как обычно, я слишком много думал о проблеме.

Просто нужно было создать пользовательскую функцию сортировки и управлять массивом вручную, вместо того, чтобы полагаться на фильтр orderBy в директиве ng-repeat:

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $filter) {
    $scope.items = [{
        "name": "John",
            "age": 25
    }, {
        "name": "Amy",
            "age": 75
    }, {
        "name": "Sarah",
            "age": 12,
    }, {
        "name": "Matt",
            "age": 55
    }, {
        "name": "Xaviour",
            "age": 2
    }];



    $scope.addChild = function () {
        var
        matt = $scope.items[findIndexByKeyValue($scope.items, 'name', 'Matt')],
            savannah = {
                "name": "Savannah",
                    "age": 2,
                    "parent": matt
            };

        console.log('matt');
        console.log(matt);

        $scope.items.splice($scope.items.indexOf(matt) + 1, 0, savannah);
        matt.child = savannah;
        $scope.matt = matt;
        $scope.savannah = savannah;
    };

    var findIndexByKeyValue = function (obj, key, value) {
        for (var i = 0; i < obj.length; i++) {
            if (obj[i][key] == value) {
                return i;
            }
        }
        return null;
    };


    $scope.sortColumnExp = '';

    $scope.sort = function (column) {
        $scope.sortColumnExp = ($scope.sortColumnExp.indexOf('-') == 0) ? column : '-' + column;
        console.log($scope.sortColumnExp);
        if ($scope.savannah) {
            $scope.items.splice($scope.items.indexOf($scope.savannah), 1);
        }
        $scope.items = $filter('orderBy')($scope.items, $scope.sortColumnExp);
        if ($scope.savannah) {
            $scope.items.splice($scope.items.indexOf($scope.savannah.parent) + 1, 0, $scope.savannah);
        }
    };

}

Работа с JSFiddle для того, что я пытался сделать... Спасибо @LcLk за хлебные крошки выше..

person RavenHursT    schedule 22.01.2014