3

将 ng-grid 与服务器端排序和分页一起使用。它工作得很好,但有一点需要注意:初始渲染会进行两次调用以从我的服务中获取数据。

我不确定在 jsFiddle 或 plunker 中复制这将是多么容易(或难)。

这是我的控制器代码:

function reportQueueController($scope, $location, reportDataService) {

    function init() {
        $scope.state = {};
    }    

    $scope.setPagingData = function (data) {
        $scope.reportQueueList = data.Data;
        $scope.totalServerItems = data.TotalItems;
    };

    $scope.$watch('pagingOptions', function(newVal, oldVal) {
        if (newVal === oldVal) return;
        getPagedDataAsync();
    }, true);

    $scope.pagingOptions = {
        pageSizes: [25, 50, 100, 'All'],
        pageSize: 25,
        currentPage: 1
    };

    $scope.$watch('gridOptions.ngGrid.config.sortInfo', function (newVal, oldVal) {
        if (newVal === oldVal) return;
        $scope.state.sortField = newVal.fields[0];
        $scope.state.sortDirection = newVal.directions[0];
        $scope.pagingOptions.currentPage = 1;
        getPagedDataAsync();
    }, true);

    $scope.gridOptions = {
        data: 'reportQueueList',
        enablePaging: true,
        enableRowSelection: false,
        showFooter: true,
        pagingOptions: $scope.pagingOptions,
        totalServerItems: 'totalServerItems',
        enableSorting: true,
        useExternalSorting: true,
        sortInfo: { fields: ['CustomerName'], directions: ['asc'] },

        filterOptions: $scope.filterOptions,
        columnDefs: [
            { field: 'CustomerName', displayName: 'Customer' },
            { field: 'ParentCustomerName', displayName: 'Parent' },
            { field: 'Name', displayName: 'Report Name' },
            { field: 'Emails', displayName: 'Email Recipients', cellTemplate: emailCellTemplate },
            { cellTemplate: editCellTemplate, width: '50px' }
        ]
    };

    function getPagedDataAsync() {
        console.log('in get data');  //this get logged twice
        reportDataService.getReportQueueList($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.state.emailAddress, $scope.state.reportSearch, $scope.state.sortField, $scope.state.sortDirection).then(function(data) {
            $scope.setPagingData(data);
        });
    };

    init();
}
4

2 回答 2

0

由于 Angular 至少会调用你的手表两次,可能更多是由于脏处理,每个 $digest 周期你可以使用 debounce。这类似于 windows 事件侦听器有时会做的事情。下划线 ( http://underscorejs.org ) 和 lo-dash ( http://lodash.com ) 都提供了_.debounce()开箱即用的功能。

_.debounce()允许你说一个函数最多每指定的毫秒数运行一次——不管这个函数实际被调用了多少次。所以你可能会做类似的事情:

var checkSortData = _.debounce(function(e) {
    $scope.state.sortField = newVal.fields[0];
    $scope.state.sortDirection = newVal.directions[0];
    $scope.pagingOptions.currentPage = 1;
    getPagedDataAsync();    
}, 500); // Run no more than once every 500 milliseconds

正如您想象的那样,underscore 使用 $timeout 来执行此操作,因此如果您愿意,可以编写自己的 debounce。

使用去抖动也可以通过最小化服务器调用来帮助提高性能/服务器负载。

但是,与其支付轮询服务器以查看它是否已更新的性能价格,您还可以考虑使用类似http://socket.io的东西。然后您不必使用手表进行轮询,您只需在客户端附加一个事件侦听器即可。这是一篇由 Brian Ford 撰写的关于在 Angular 中使用 socket.io 的文章:http: //www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

于 2013-11-12T15:36:15.163 回答
0

您的代码看起来正确,请检查您是否使用了两次不显眼的 js 文件,例如

jquery.validate.unobtrusive.js
jquery.validate.unobtrusive.min.js

或者同一个文件添加了两次。

于 2014-11-17T17:29:03.493 回答