角度js中的百慕大三角形:$ resource + directive + pagination

时间:2014-11-05 15:44:03

标签: javascript angularjs angularjs-directive pagination angularjs-ng-repeat

Hi angular js专家,

我对使用$ resource,directive和pagination感到很困惑。我想要的是创建一个表指令,可以对分页进行排序,过滤和分页 有一些已经创建的表组件,但我处于angularjs学习过程的开始,所以我想了解如何创建这样的东西。
此外,我阅读了很多论坛和stackoverflow线程,我有一个部分解决方案,但我仍然没有一个有效的解决方案。

所以我创建了一个指令:

app.directive("customTable", function($compile, $document) {
    function link(scope, element, attrs) {
        var html = "<table><tr>";
        html += "<td style='width: {{ h.width }} px;white-space: nowrap;' ng-repeat='h in headers'>";
        html += "<input style='width: {{ h.width }};display: block;' type='text' ng-model='filters[h.column]'> </td> </tr>";
        html += "<tr ng-repeat='record in customTableData"; 
        var htmlTableTd = "";
        var arrayLength = scope.headers.length;
        for (var i = 0; i < arrayLength; i++) {
            html += " | filter:{" + scope.headers[i].column + ":filters." + scope.headers[i].column + "}";
            htmlTableTd += "<td>{{ record." + scope.headers[i].column + " }}</td>";
        }
        html += "'>";
        html += htmlTableTd;
        html += "</tr> </table>";
        element.html(html);
        $compile(element.contents())(scope);
    }

    return {
        restrict: "E",
        link: link
    };
});

还有一个控制器:

app.controller("administration.service.controller", function ($scope, $resource) {
    $scope.headers = [
        {column: "name", width: "150px"},
        {column: "serviceType", width: "100px"}
    ];
    $scope.filters = {};
    var serviceManager = $resource("list"); 
    $scope.customTableData = serviceManager.query();
});

我尝试使用bootstrap分页,但我应该在指令中使用一些过滤的customTableData(在ngRepeat中)。但是,由于customTableData是一个promise,而且构建指令时尚未处理,所以它是空的,即过滤的customTableData也是空的。一种解决方案是在控制器中使用then(...)方法并从控制器调用指令的函数,但我不知道如何做到这一点并不是一个优雅的解决方案。
我的问题有没有优雅的解决方案?

谢谢,

1 个答案:

答案 0 :(得分:0)

我有一个解决方案,见下文(我使用了以下2个样本,感谢他们:http://jsfiddle.net/2ZzZB/56/http://jsfiddle.net/7czsM/1/

指令:

app.filter('startFrom', function() {
    return function(input, start) {
        start = +start; //parse to int
        return input.slice(start);
    }
});

app.directive("customTable", function($compile, $document) {

    function link(scope, element, attrs) {
        // variables for pagination
        scope.currentPage = 0;
        scope.pageSize = 10;
        scope.numberOfPages=function(){
            return Math.ceil(scope.filteredCustomTableData.length/scope.pageSize);                
        }

        // for sorting
        scope.sort = {
            column: '',
            descending: false
        };

        scope.changeSorting = function(column) {
            var sort = scope.sort;
            if (sort.column == column) {
                sort.descending = !sort.descending;
            } else {
                sort.column = column;
                sort.descending = false;
            }
        };

        var arrayLength = scope.headers.length;
        var html = "<table> <tr>";
        // 1. building the header
        for (var i = 0; i < arrayLength; i++) {
            html += "<th ng-click='changeSorting(\"" + scope.headers[i].column + "\")'> " + scope.headers[i].label + " </th>";
        }
        // 2. building the filters
        html += "</tr> <tr> <td style='width: {{ h.width }} px;white-space: nowrap;' ng-repeat='h in headers'>";
        html += "<input style='width: {{ h.width }};display: block;' type='text' ng-model='filters[h.column]'> </td> </tr>";
        // 3. building the table rows
        // sample: <tr ng-repeat='record in (filteredCustomTableData = (customTableData | filter:{name:filters.name} | filter:{serviceType:filters.serviceType}) | startFrom:currentPage*pageSize | limitTo:pageSize | orderBy:sort.column:sort.descending')>"
        html += "<tr ng-repeat='record in (filteredCustomTableData = (customTableData";

        var htmlTableTd = "";
        // first creating the filters in the ngRepeat (| filter:{name:filters.name} | filter:{serviceType:filters.serviceType}| ...)
        // and after that adding the real table rows -> 
        for (var i = 0; i < arrayLength; i++) {
            html += " | filter:{" + scope.headers[i].column + ":filters." + scope.headers[i].column + "}";
            htmlTableTd += "<td>{{ record." + scope.headers[i].column + " }}</td>";
        }
        html += " | orderBy:sort.column:sort.descending) | startFrom:currentPage*pageSize | limitTo:pageSize)'>";
        html += htmlTableTd;
        html += "</tr> </table>";

        // adding the pagination buttons
        html += "<button ng-disabled='currentPage == 0' ng-click='currentPage=currentPage-1'>Previous</button>{{currentPage+1}}/{{numberOfPages()}}";
        html += "<button ng-disabled='currentPage >= filteredCustomTableData.length/pageSize - 1' ng-click='currentPage=currentPage+1'>Next</button>";

        element.html(html);
        $compile(element.contents())(scope);
    }

    return {
        restrict: "E",
        link: link
    };

});

控制器:

app.controller("administration.service.controller", function ($scope, $resource) {

    $scope.headers = [
        {column: "name", width: "150px", label: "Name"},
        {column: "serviceType", width: "100px", label: "Service Type"}
    ];

    $scope.filters = {};

    var serviceManager = $resource("list");

    $scope.customTableData = serviceManager.query();
});