Question

I have problem with sorting in directive. I want to dynamically create a table header using object with 'Name' and 'Text' properties. 'Name' contains logic name and 'Text' display name of field. Everything works fine when I do not use predicate in ng-repeat and dynamic columns.

HTML:

<ng-my-table 
    ng-columns="[
            { Text: 'First name', Name: 'FirstName' },
            { Text: 'Last name', Name: 'LastName' }
        ]">
</ng-my-table>

Directive template:

<thead>
    <tr>
        <th ng-repeat="column in ngColumns" ng-click="predicate='{{column.Name}}'; reverse=!reverse">{{column.Text}}</th>
    </tr>
</thead>

Compiled table header looks same like static but does not work.

Can someone help me? Thanks.

Was it helpful?

Solution 3

Here is working sample:

Directive template:

<thead>
    <tr>
        <th ng-repeat="column in ngColumns" ng-click="SortColumn(column.Name)">{{column.Text}}</th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="item in ngModel | orderBy:predicate:reverse">
    ...
    ...

Directive controller:

controller: ["$scope", "$http", function ($scope, $http) {
            // convert string to object
            $scope.ngColumns = $scope.$eval($scope.ngColumns);
            // models for sorting
            $scope.predicate = $scope.ngColumns[0].Name;
            $scope.reverse = false;
            // sort function
            $scope.SortColumn = function (columnName) {
                $scope.predicate = columnName;
                $scope.reverse = !$scope.reverse
            }
        }]

I hope it helps someone.

OTHER TIPS

You need to associate the predicate with the scope object being looped.

That is, your markup should be:

<th ng-repeat="column in ngColumns| orderBy:predicate:reverse"
    ng-click="predicate='{{column.Name}}'; reverse=!reverse">{{column.Text}}</th>

However, a suggestion - move the code inside the ng-click directive to the scope's controller function - easier to maintain.

So, with the function in your controller like this:

//Don't forget to initialize
$scope.predicate = $scope.ngColumns[0].Name;
$scope.reverse = false;

$scope.sortColumn = function (columName) {
    $scope.predicate = columnName;
    $scope.reverse = !$scope.reverse
}

your view code will now look like:

<th ng-repeat="column in ngColumns| orderBy:predicate:reverse"
        ng-click="sortColumn(column.Name)">{{column.Text}}</th>

predicate='{{column.Name}}'; looks like a problem source.

ng-click directive doesnot use angular expression syntax. Try to write this way predicate=column.Name;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top