-->

Is it possible to have a select drop down inside o

2019-03-11 13:03发布

问题:

I have coded the following:

$scope.gridOptions = {
    data: 'myData',
    enableCellEdit: true,
    multiSelect: false,
    columnDefs: [
        { field: 'Id', displayName: 'Id' },
        { field: 'Name', displayName: 'Name', enableCellEdit: true, editableCellTemplate: cellEditableTemplate },
        { field: 'Description', displayName: 'Description', enableCellEdit: true, editableCellTemplate: cellEditableTemplate }
    ]
};

The myData actually contains four colums Id, Name, Status and Description. Where status is a simple javascript array with three types of status called myStatus.

Is it possible for me to somehow link in the data from myStatus to a field in the ng-grid so I can then select a new value from a select drop down?

回答1:

Here is output of some experiment.

http://plnkr.co/edit/W1TkRgsp0klhqquxaiyc?p=preview

It seems that you can put select in cell template. And you can make use of row object to retrieve whatever you need. I used row.rowIndex to property access to the original data.

template example:

<div>
  <select ng-model="myData[ row.rowIndex ].myStatus">
    <option ng-repeat="st in statuses">{{st}}</option>
  </select>
</div>

(It would be beutiful if we can write to ogirinal data through row object. I do not know how.)



回答2:

The way tosh shimayama are doing it, will not allow for sorting the table in any other order than the model array.

This is kind of an ugly way to do it, but I took a quick look in the source code for ng-grid and found that they use regexp to insert the ng-model. So by using the same variable, COL_FIELD, in your code you can make ng-grid insert the correct model.

<div>
  <select ng-model="COL_FIELD">
    <option ng-repeat="status in statuses">{{status}}</option>
  </select>
</div>

Here is a plunker with a working example: http://plnkr.co/edit/Yj2qmI?p=preview



回答3:

A more complete/tidier way to do this in ng-grid 2.x I've included in a plunker here: http://plnkr.co/edit/VABAEu?p=preview, leveraging content from another similar question on stackoverflow here: AngularJS and ng-grid - auto save data to the server after a cell was changed

In summary, my format for the editable field template looks like so:

      $scope.statuses = {1: 'active', 2: 'inactive'};
      $scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" 
         ng-input="COL_FIELD" ng-model="COL_FIELD" 
         ng-options="id as name for (id, name) in statuses" 
         ng-blur="updateEntity(row)" />';

I've provided a blog post that has a more thorough walkthrough of the end-to-end code: http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/

Ng-grid (ui-grid) 3.0 is close to being released, and offers different ways to do editable grids. I have a post on that here: http://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/



回答4:

I can't take credit for the entire solution. I just put the pieces together. My goal was to preserve three-way binding.

Template should look something like this:

        $scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-options="value.id as value.label for value in OptionsList}" />';
COL_FIELD of course essential to keep the reference to correct cell.

You can capture the change natively:

$scope.$on('ngGridEventEndCellEdit', function (evt) {
            console.log(evt.targetScope.row.entity);
            WaitListArray.$save(evt.targetScope.row.entity)
                .then(function (ref) {
                    console.log('saved');
                });
        });

In this case WaitListArray is my Firebase/AngularFire Array for the table. Using this method, I was able to preserve my tree-way binding.

Field (ng-options):

{
  field: 'status',
  displayName: 'Status',
  enableCellEditOnFocus: true,
  editableCellTemplate: $scope.cellSelectEditableTemplate,
  cellFilter: 'mapStatus:OptionsList'
}

I added filter to replace id with label for my dropdown values.

.filter('mapStatus', function() {
  return function(input, OptionsList) {
    var _out = 'unknown';
    angular.forEach(OptionsList, function(value, key) {

      if (value && value.id == input) {
        _out = value.label;
      }
    });
    return _out;

  };
})

In the above, OptionsList is my dropdown values array example: {id:1,label:"label1"}

I found this solution highly reusable. Hopefully, it saves time for someone.