Angular ngGrid выбирает строку при загрузке страницы

Мой вопрос является продолжением этого вопроса

Получение выбранных строк из ng-grid?

плункер — http://plnkr.co/edit/DiDitL?p=preview

Мне нужно, чтобы строка была выбрана при загрузке страницы, и мне нужно избегать прослушивания «ngGridEventData»

вызов $scope.gridOptions.selectRow(2, true); в теле контроллера не работает, так как сетка не загружена.

избегание прослушивания ngGridEventData связано с тем, что мне нужен контроллер для прослушивания события, инициированного ранее, и на основе этого мне нужно выбрать строку nggrid.

есть идеи?


person Sanath    schedule 29.08.2013    source источник


Ответы (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
  • послеSelectionChange x2
  • ngGridEventData
  • послеSelectionChange 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)});
    }
}));
person valepu    schedule 10.04.2015

Добавьте $timeout в свой контроллер и сделайте следующее:

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

Пример: http://plnkr.co/edit/hDv7b8?p=preview

person user508994    schedule 15.10.2013
comment
Почему должен быть тайм-аут? Любая информация об этом в угловых документах? - person Jaanus; 16.04.2014
comment
Мне нужно поставить, потому что? - person Jaanus; 17.04.2014
comment
Упс. Вам нужно поместить его в $ timeout, потому что сетка не инициализируется при создании контроллера. Другим способом было бы сделать директиву. - person user508994; 18.04.2014
comment
Ик. Запах кода. Если таймер слишком короткий, он не будет работать, так как сетка будет неопределенной. Если слишком долго, пользователь будет ждать, пока произойдет выбор. Я гуглил и не нашел хорошего решения, но я, конечно, не буду использовать это. Любой профессионал, представляющий это для проверки кода, не получит очень хорошей годовой оценки. Решение должно управляться событиями, при этом событие означает, что сетка полностью заполнена. Может в ng-grid v3? - person Mawg says reinstate Monica; 30.04.2014
comment
@Mawg Таймер не будет ни слишком коротким, ни слишком длинным. Обратите внимание, что в $timeout службу Angular не передается числовой параметр. Эта служба возвращает обещание, которое разрешается в следующем цикле дайджеста после задержки. Когда задержка равна 0 (по умолчанию), это означает самый следующий цикл дайджеста. Это типичный вариант использования службы $timeout, и когда в теле такого контроллера он конкретно сообщает Angular, пусть контроллер и все остальное завершат загрузку, затем разрешите это обещание (т. е. запустите этот обратный вызов). - person daemonexmachina; 21.04.2016
comment
@Mawg Это выглядит неправильно, но это не так. Это фреймворки для вас, у всех есть свои причуды. (Я знаю, что прошло два года, так что извините, но вы были очень самоуверенны! Я надеюсь, что люди, проводящие проверку кода, знают, как обойти используемый ими фреймворк...) - person daemonexmachina; 21.04.2016
comment
Спасибо за новость (лучше поздно, чем никогда ;-). Этот проект заброшен, но я как раз собираюсь добавить сетку в новый проект, так что приму это во внимание. Спасибо (+1). - person Mawg says reinstate Monica; 21.04.2016

Решение без таймаута можно найти здесь: https://github.com/angular-ui/ui-grid/issues/2267 и здесь: Pre -Выбрать строки при загрузке с помощью 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]);
                }
            };

По-видимому, для модификации Rows требуется v3.0.0-rc.22+.

person rob2universe    schedule 23.12.2015

Хорошо, ответ был присужден давно, но я все еще думаю, что он пахнет кодом (не в обиду автору, но он неоптимален).

Что я сделал, так это использовал событие сетки 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);                               
                       }
                   }
person Mawg says reinstate Monica    schedule 03.05.2014
comment
Я могу подтвердить, что это не будет работать на прокручиваемых сетках. событие будет срабатывать только для показанных строк (на самом деле я не уверен, что оно срабатывает для каждой строки. для меня оно срабатывало 4 раза: дважды с рендерингом 0 строк и дважды с рендерингом 6 строк, затем оно перестало срабатывать) - person valepu; 10.04.2015