Angular ngGrid选择页面加载行

时间:2013-08-29 07:29:35

标签: javascript angularjs angularjs-scope angular-ui ng-grid

我的问题是这个问题的延伸

Getting select rows from ng-grid?

plunker - http://plnkr.co/edit/DiDitL?p=preview

我需要在页面加载时选择一行,我需要避免收听'ngGridEventData'

调用$ scope.gridOptions.selectRow(2,true);由于网格尚未加载,因此控制器主体失败。

避免收听ngGridEventData是因为我需要控制器监听之前触发的事件,并根据我需要选择nggrid行。

任何想法?

4 个答案:

答案 0 :(得分:14)

$timeout添加到您的控制器并执行以下操作:

$timeout(function() { 
    $scope.gridOptions.selectRow(2, true); 
});

示例:http://plnkr.co/edit/hDv7b8?p=preview

答案 1 :(得分:6)

可以在此处找到没有超时的解决方案: https://github.com/angular-ui/ui-grid/issues/2267 和这里: Pre-Select rows on load with angular-ui-grid

$scope.gridOptions = {
...
                onRegisterApi : function (gridApi) {
                    $scope.gridApi = gridApi;
                    $scope.gridApi.grid.modifyRows($scope.gridOptions.data);
                    $scope.gridApi.selection.selectRow($scope.gridOptions.data[0]);
                }
            };

显然,modifyRows需要v3.0.0-rc.22 +

答案 2 :(得分:4)

对我来说,没有一个答案有效(我使用ng-grid v2.0.14)。

选择的答案可能是因为数据不大或未通过ajax调用加载,否则您无法在ngGridEventData之前选择一行,因为在渲染行时触发了事件而您无法选择如果尚未渲染,则为一行 如果这些条件中的任何一个失败或者网格花费的时间比平时要多,那么所选答案将无效。

我有一个可滚动的网格,大约有2000行,但是我对听取ngGridEvent数没有任何限制,所以我就这样做了,虽然它对我来说有一个奇怪的行为:ngGridEventData为我激发了4次,两次数据从ajax调用到达之前和之后两次 我使用了这个jquery插件http://benalman.com/projects/jquery-throttle-debounce-plugin/(它甚至可以在没有jQuery的情况下使用)来使它只调用一次函数。

由于这还不够,“selectRow / selectItem”函数会两次触发“afterSelectionChange”事件(由于某种原因第一次出现错误的行)。这是我必须要做的,以确保只触发一次事件,并且仅针对正确的行。

这就是我发生的事情:

  • ngGridEventData(没有afterSelectionChange触发,可能是因为没有渲染的行)
  • ngGridEventData(没有afterSelectionChange触发,可能是因为没有渲染的行)
  • Ajax调用检索数据
  • 延迟(可能是渲染)
  • ngGridEventData
  • afterSelectionChange x2
  • ngGridEventData
  • afterSelectionChange x2

所以我必须使用它:

    为了确保函数在延迟期间只调用一次(超时很低,因为调用彼此接近,并且渲染的行检查确保第一次调用不是正在使用的调用),
  • 去抖动/ LI>
  • 检查渲染的行是否> 0以确保在缓慢的系统(或慢速连接)上没有触发前2个事件,其中延迟和数据加载可能需要一些时间
  • 可选择使用rowItem.selected来避免另一个“bug”,因为afterSelectionChange事件即使在选择一行时也会触发两次(一次为未选中的行,一次为所选行)
  • 使用fireOnlyOnce变量来避免调用afterSelectionChange函数两次。

以下是示例代码:

$scope.fireOnlyOnce=true;
$scope.gridOptions = {
    //Stuff
    afterSelectionChange: function (rowItem) {
        if($scope.fireOnlyOnce){
            if(rowItem.selected){
                //Do stuff
            }
        } else {
            $scope.fireOnlyOnce=true;
        }
    }
};

$scope.$on('ngGridEventData', jQuery.debounce(100, function (row, event){   
    var renderedRows = row['targetScope'].renderedRows.length;
    if(renderedRows>0){
        $scope.fireOnlyOnce=false;
        $timeout(function(){$scope.gridOptions.selectRow(2, true)});
    }
}));

答案 3 :(得分:2)

好的,很久以前就给出了答案,但我仍然认为它有代码味道(海报没有冒犯,但它 次优。

我所做的是使用网格的ngGridEventData事件。

你必须要小心,因为它会多次触发(每次添加一次),但是,因为我们知道将填充网格的数据大小,并且自从事件发生以来,允许我们检查已渲染的行数,我们可以判断最后一行的渲染时间,这意味着网格没有完全显示(注意:我没有使用滚动网格测试它,其中一些行可能不可见,有人可以确认它是否适用于帽子?我个人从不使用滚动网格(它是浏览器页面,而不是桌面)。

这样的事情:

    $scope.$on('ngGridEventData', function (row, event) 
               {   
                   if (event == $scope.vehicleTypeGridOptions.gridId)
                   {
                       console.info('@+@ vehicleTypeGridOptions  grid updated');
                       var renderedRows = row['targetScope'].renderedRows.length;
                       console.info('renderedRows = ' + renderedRows + '; num data rows = ' + $scope.vehicleTypesGridData.length);                       

                       if (renderedRows == 0)
                       {
                           return;
                       }

                       // if grid rowcount = dat length then it's fully displayed
                       if (renderedRows == $scope.vehicleTypesGridData.length) 
                       {
                           console.log('vehicleTypeGrid fully rendered. Select row zer0, then populate vehicleDescriptionGrid');
                           console.info('Select row zer0');                                
                           $scope.vehicleTypeGridOptions.selectItem(0, true);   // Grid rendered, select first row
                           // console.table($scope.vehicleTypeGridOptions.selectedItems);
                           var vehicle_type =     $scope.vehicleTypeGridOptions.selectedItems[0].vehicle_type;
                           console.info(vehicle_type);                               
                       }
                   }