角ngGrid选择页面负载上的行

时间:2021-11-01 11:14:21

My question is an extension to thisquestion

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

Getting select rows from ng-grid?

从ng-grid获取选择行?

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

砰砰作响——http://plnkr.co/edit/DiDitL?p=preview

I need a row to be selected on page load and I need to avoid listening to 'ngGridEventData'

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

calling $scope.gridOptions.selectRow(2, true); in the controller body fails since the grid has not been loaded.

调用scope.gridOptions美元。selectRow(真实);由于没有加载网格,因此控制器主体失败。

avoiding listening to ngGridEventData is due to the fact that I need the controller to listen to an event triggered before and based on that I need to select the nggrid row.

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

any ideas?

什么好主意吗?

4 个解决方案

#1


4  

For me, none of the answers worked (i use ng-grid v2.0.14).

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

The selected answer works probably because data is either not big or is not loaded through an ajax call otherwise you can't select a row "before" ngGridEventData since the event is fired when the rows are rendered and you can't select a row if it hasn't been rendered yet.
Should any of these conditions fail or the grid take too much time than usual to render then the selected answer will not work.

所选择的答案可能是有效的,因为数据不是很大,就是没有通过ajax调用加载,否则您不能在“ngGridEventData”之前选择一个行,因为事件是在呈现行时触发的,如果还没有呈现行,您就不能选择一个行。如果这些条件中的任何一种都失败了,或者网格花费了比通常更多的时间来呈现,那么所选的答案将无法工作。

I have a scrollable grid with about 2000 rows, but I haven't any restriction on listening to the ngGridEventData so i worked on that, although it has a weird behavior for me: The ngGridEventData fires exactly 4 times for me, twice before data arrives from the ajax call and twice after.
I used this jquery plugin http://benalman.com/projects/jquery-throttle-debounce-plugin/ (it can be used even without jQuery though) to make it so that the function was called only once.

我有一个可滚动的网格与大约2000行,但我没有任何限制听ngGridEventData所以我工作,尽管它有一个奇怪的行为对我来说:ngGridEventData火灾完全为我4次,前两次数据到ajax调用和之后的两倍。我使用了jquery插件http://benalman.com/projects/jquery-throttle-debounce-plugin/(即使没有jquery也可以使用它)使这个函数只被调用一次。

And since this is not enough, the "selectRow/selectItem" function triggers the "afterSelectionChange" event twice (the first time with the wrong row, for some reason). This is what i had to do to make sure that the event is fired only once and only for the correct row.

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

This is what happens for me:

这就是发生在我身上的事情:

  • ngGridEventData (no afterSelectionChange triggers, probably because there are no rendered rows)
  • ngGridEventData(没有afterSelectionChange触发器,可能是因为没有呈现的行)
  • ngGridEventData (no afterSelectionChange triggers, probably because there are no rendered rows)
  • ngGridEventData(没有afterSelectionChange触发器,可能是因为没有呈现的行)
  • Ajax call to retrieve data
  • 调用Ajax来检索数据
  • delay (probably rendering)
  • 可能延迟(呈现)
  • ngGridEventData
  • ngGridEventData
  • afterSelectionChange x2
  • afterSelectionChange x2
  • ngGridEventData
  • ngGridEventData
  • afterSelectionChange x2
  • afterSelectionChange x2

So i had to use this:

所以我必须用这个:

  • debounce to make sure the function is called only once during the delay (the timeout is low since the calls are close to one another in pair, and the rendered rows checks makes sure the first call is not the one being used)
  • 为了确保在延迟期间只调用一次函数(超时很低,因为调用是成对的,并且呈现的行检查确保第一个调用不是正在使用的)
  • check that the rendered rows are > 0 to make sure the first 2 events are not triggered on slow sistems (or slow connection) where the delay and data load might take some time
  • 检查呈现的行是否为>,以确保在延迟和数据加载可能需要一些时间的缓慢sistems(或慢连接)上没有触发前两个事件
  • Optionally use rowItem.selected to avoid another "bug" since the afterSelectionChange event fires twice even when selecting a row (once for the row being unselected and once for the selected row)
  • 有选择地使用rowItem。选择此选项是为了避免另一个“bug”,因为afterSelectionChange事件即使在选择一个行时也会触发两次(一次是未选中的行,一次是选中的行)
  • use the fireOnlyOnce variable to avoid calling twice the afterSelectionChange function.
  • 使用fireOnlyOnce变量,以避免调用两次afterSelectionChange函数。

Here's a sample code:

下面是一个示例代码:

$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)});
    }
}));

#2


14  

Add $timeout to your Controller and do this:

向控制器添加$timeout并执行以下操作:

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

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

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

#3


6  

A solution without timeout can be found here: https://github.com/angular-ui/ui-grid/issues/2267 and here: Pre-Select rows on load with angular-ui-grid

可以在这里找到一个没有超时的解决方案:https://github.com/angular-ui/ui-grid/issues es/2267以及这里:使用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]);
                }
            };

Apparently modifyRows requires v3.0.0-rc.22+

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

#4


2  

Ok, the answer was awarded long ago, but I still think that it has a code smell (no offence to the poster, but it is sub-optimal.

好吧,答案很早以前就已经给出了,但我仍然认为它有一种代码味道(对海报来说没有冒犯之处,但它是次优的。

What I did was use the grid's ngGridEventData event.

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

You have to be careful, since it fires multiple times (once for each row added), but, since we know the size of the data which will populate the gird and, since the event, allows us to examine how many rows have been rendered, we can tell when the last row is rendered, meaning that the grid is not fully displayed (NOTE: I did not test this with scrolling grids, where some rows may not be visible, could someone please confirm if it works in hat case? I personally never use scrolling grids (it's a browser page, not a Desktop).

你必须小心,因为它多次火灾(曾经为每一行添加),但是,因为我们知道数据的大小将填充嘲骂,事件以来,允许我们检查已经呈现多少行,我们可以告诉当渲染最后一行,即网格没有完全显示出来(注意:我没有测试这个滚动网格,有些行可能不可见,可以请确认如果它工作在帽子的人?我个人从来不使用滚动网格(它是一个浏览器页面,而不是桌面)。

Something like this:

是这样的:

    $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);                               
                       }
                   }

#1


4  

For me, none of the answers worked (i use ng-grid v2.0.14).

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

The selected answer works probably because data is either not big or is not loaded through an ajax call otherwise you can't select a row "before" ngGridEventData since the event is fired when the rows are rendered and you can't select a row if it hasn't been rendered yet.
Should any of these conditions fail or the grid take too much time than usual to render then the selected answer will not work.

所选择的答案可能是有效的,因为数据不是很大,就是没有通过ajax调用加载,否则您不能在“ngGridEventData”之前选择一个行,因为事件是在呈现行时触发的,如果还没有呈现行,您就不能选择一个行。如果这些条件中的任何一种都失败了,或者网格花费了比通常更多的时间来呈现,那么所选的答案将无法工作。

I have a scrollable grid with about 2000 rows, but I haven't any restriction on listening to the ngGridEventData so i worked on that, although it has a weird behavior for me: The ngGridEventData fires exactly 4 times for me, twice before data arrives from the ajax call and twice after.
I used this jquery plugin http://benalman.com/projects/jquery-throttle-debounce-plugin/ (it can be used even without jQuery though) to make it so that the function was called only once.

我有一个可滚动的网格与大约2000行,但我没有任何限制听ngGridEventData所以我工作,尽管它有一个奇怪的行为对我来说:ngGridEventData火灾完全为我4次,前两次数据到ajax调用和之后的两倍。我使用了jquery插件http://benalman.com/projects/jquery-throttle-debounce-plugin/(即使没有jquery也可以使用它)使这个函数只被调用一次。

And since this is not enough, the "selectRow/selectItem" function triggers the "afterSelectionChange" event twice (the first time with the wrong row, for some reason). This is what i had to do to make sure that the event is fired only once and only for the correct row.

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

This is what happens for me:

这就是发生在我身上的事情:

  • ngGridEventData (no afterSelectionChange triggers, probably because there are no rendered rows)
  • ngGridEventData(没有afterSelectionChange触发器,可能是因为没有呈现的行)
  • ngGridEventData (no afterSelectionChange triggers, probably because there are no rendered rows)
  • ngGridEventData(没有afterSelectionChange触发器,可能是因为没有呈现的行)
  • Ajax call to retrieve data
  • 调用Ajax来检索数据
  • delay (probably rendering)
  • 可能延迟(呈现)
  • ngGridEventData
  • ngGridEventData
  • afterSelectionChange x2
  • afterSelectionChange x2
  • ngGridEventData
  • ngGridEventData
  • afterSelectionChange x2
  • afterSelectionChange x2

So i had to use this:

所以我必须用这个:

  • debounce to make sure the function is called only once during the delay (the timeout is low since the calls are close to one another in pair, and the rendered rows checks makes sure the first call is not the one being used)
  • 为了确保在延迟期间只调用一次函数(超时很低,因为调用是成对的,并且呈现的行检查确保第一个调用不是正在使用的)
  • check that the rendered rows are > 0 to make sure the first 2 events are not triggered on slow sistems (or slow connection) where the delay and data load might take some time
  • 检查呈现的行是否为>,以确保在延迟和数据加载可能需要一些时间的缓慢sistems(或慢连接)上没有触发前两个事件
  • Optionally use rowItem.selected to avoid another "bug" since the afterSelectionChange event fires twice even when selecting a row (once for the row being unselected and once for the selected row)
  • 有选择地使用rowItem。选择此选项是为了避免另一个“bug”,因为afterSelectionChange事件即使在选择一个行时也会触发两次(一次是未选中的行,一次是选中的行)
  • use the fireOnlyOnce variable to avoid calling twice the afterSelectionChange function.
  • 使用fireOnlyOnce变量,以避免调用两次afterSelectionChange函数。

Here's a sample code:

下面是一个示例代码:

$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)});
    }
}));

#2


14  

Add $timeout to your Controller and do this:

向控制器添加$timeout并执行以下操作:

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

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

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

#3


6  

A solution without timeout can be found here: https://github.com/angular-ui/ui-grid/issues/2267 and here: Pre-Select rows on load with angular-ui-grid

可以在这里找到一个没有超时的解决方案:https://github.com/angular-ui/ui-grid/issues es/2267以及这里:使用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]);
                }
            };

Apparently modifyRows requires v3.0.0-rc.22+

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

#4


2  

Ok, the answer was awarded long ago, but I still think that it has a code smell (no offence to the poster, but it is sub-optimal.

好吧,答案很早以前就已经给出了,但我仍然认为它有一种代码味道(对海报来说没有冒犯之处,但它是次优的。

What I did was use the grid's ngGridEventData event.

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

You have to be careful, since it fires multiple times (once for each row added), but, since we know the size of the data which will populate the gird and, since the event, allows us to examine how many rows have been rendered, we can tell when the last row is rendered, meaning that the grid is not fully displayed (NOTE: I did not test this with scrolling grids, where some rows may not be visible, could someone please confirm if it works in hat case? I personally never use scrolling grids (it's a browser page, not a Desktop).

你必须小心,因为它多次火灾(曾经为每一行添加),但是,因为我们知道数据的大小将填充嘲骂,事件以来,允许我们检查已经呈现多少行,我们可以告诉当渲染最后一行,即网格没有完全显示出来(注意:我没有测试这个滚动网格,有些行可能不可见,可以请确认如果它工作在帽子的人?我个人从来不使用滚动网格(它是一个浏览器页面,而不是桌面)。

Something like this:

是这样的:

    $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);                               
                       }
                   }