12

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

从 ng-grid 获取选择行?

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

我需要在页面加载时选择一行,并且我需要避免收听“ngGridEventData”

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

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

有任何想法吗?

4

4 回答 4

14

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

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

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

于 2013-10-15T21:12:06.050 回答
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+

于 2015-12-23T10:53:14.627 回答
4

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

选择的答案可能是因为数据不大或没有通过 ajax 调用加载,否则您无法在“ngGridEventData”“之前”选择一行,因为在呈现行时会触发该事件,如果它还没有被渲染。
如果这些条件中的任何一个失败或网格渲染时间比平时多,则所选答案将不起作用。

我有一个大约 2000 行的可滚动网格,但我对收听 ngGridEventData 没有任何限制,所以我一直在努力,尽管它对我来说有一个奇怪的行为: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

所以我不得不使用这个:

  • debounce 以确保函数在延迟期间仅被调用一次(超时时间很低,因为调用彼此接近,并且呈现的行检查确保第一个调用不是正在使用的调用)
  • 检查渲染的行是否 > 0 以确保前 2 个事件不会在延迟和数据加载可能需要一些时间的慢速系统(或慢速连接)上触发
  • 可选择使用 rowItem.selected 来避免另一个“错误”,因为即使在选择行时 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)});
    }
}));
于 2015-04-10T14:30:17.180 回答
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);                               
                       }
                   }
于 2014-05-03T09:34:40.743 回答