在ui-grid 3.0中标记修改后的单元格/行$ dirty

时间:2015-09-18 00:00:26

标签: angularjs angular-ui-grid

我有一个几乎像它应该的ALMOST的plunker。我必须添加一个要求,我无法在文档或谷歌上找到它。

网格设置(如Excel),您可以在其中开始编辑,Tab键将从一行移动到另一行。如果进行了更改,我需要一些方法将单元格标记为$ dirty。

需求是一个更新按钮,用于保存整个网格,如果有任何更改(再次,他希望它像Excel一样)。

这里是plunker

问题:双击可编辑单元格(名称,状态,M,T,W,H,F),Tab键将循环显示整个网格。如果更改了单元格值,我需要一种方法将其标记为脏!

CODE: (index.html的)

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="lodash.js@*" data-semver="3.10.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css" />
    <link rel="stylesheet" href="main.css" type="text/css" />
  </head>

  <body>
    <div ng-controller="MainCtrl">
      <strong>Data Length:</strong>
 {{ gridOptions.data.length | number }}
        <br />
      <strong>Last Cell Edited:</strong>
 {{msg.lastCellEdited}}
        <br />
      <div ui-grid="gridOpts" ui-grid-edit="" ui-grid-cellnav="" class="grid"></div>
    </div>
    <script src="app.js"></script>
  </body>

</html>

(app.js)

var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);

app.controller('MainCtrl', ['$scope', '$http', function($scope, $http) {
  $scope.$scope = $scope;
  $scope.pending_view = true;
  $scope.gridOpts = {
    enableCellEditOnFocus: true,
    enableGridMenu: true
  };

   var dataset = [{
    vote_pending: false,
    has_comment: false,
    is_stale: false,
    is_watched: false,
    disbursement_issue: false,
    name: "Jon",
    status: 1,
    M: 9,
    T: 9,
    W: 9,
    H: 9,
    F: 4
  }, {
    vote_pending: true,
    has_comment: true,
    is_stale: true,
    is_watched: true,
    disbursement_issue: true,
    name: "Robbie",
    status: 1,
    M: 8,
    T: 8,
    W: 8,
    H: 8,
    F: 8
  }, {
    vote_pending: false,
    has_comment: false,
    is_stale: true,
    is_watched: true,
    disbursement_issue: false,
    name: "Brad",
    status: 1,
    M: 8,
    T: 8,
    W: 8,
    H: 8,
    F: 8
  }, {
    vote_pending: false,
    has_comment: true,
    is_stale: false,
    is_watched: false,
    disbursement_issue: false,
    name: "Paul",
    status: 1,
    M: 8,
    T: 8,
    W: 8,
    H: 8,
    F: 8
  }, {
    vote_pending: false,
    has_comment: true,
    is_stale: false,
    is_watched: true,
    disbursement_issue: false,
    name: "Billie",
    status: 2,
    M: 8,
    T: 4,
    W: 4,
    H: 4,
    F: 0
  }];

  $scope.getTotal=function(a, b, c, d, e) {
    return a+b+c+d+e;
  };

  $scope.gridweek = true;

  var sByName = _.sortBy(dataset, 'name');
  var sPending = _.sortByAll(dataset, ['is_watched', 'vote_pending', 'has_comment', 'disbursement_issue', 'is_stale']).reverse();

  $scope.gridOpts.data = sPending;

  $scope.pendingSort = function() {
    if($scope.gridOpts.data === sByName) {
      $scope.gridOpts.data = sPending;
    } else if($scope.gridOpts.data === sPending) {
      $scope.gridOpts.data = sByName;
    }
  };

  $scope.gridOpts.columnDefs = [
    {
      name: 'id',
      enableCellEdit: false,
      enableColumnMenu: false,
      headerCellTemplate: 'pending.hdr.html',
      cellTemplate: 'pending.icons.html',
      width: '15%'
    }, 
    {
      name: 'name',
      enableCellEdit: true,
      displayName: 'Name',
      cellClass: 'text-left cBlue',
      headerCellClass: 'text-center bGreen',
      enableColumnMenu: false,
      width: '12%'
    }, 
    {
      name: 'status',
      enableCellEdit: true,
      displayName: 'Status',
      editableCellTemplate: 'ui-grid/dropdownEditor',
      enableColumnMenu: false,
      cellClass: 'text-left cBlue',
      cellFilter: 'mapStatus',
      headerCellClass: 'text-center bGreen',
      editDropdownValueLabel: 'status',
      editDropdownOptionsArray: [
        {
          id: 1,
          status: 'FT'
        }, 
        {
          id: 2,
          status: 'PT'
        }
      ],
      visible: $scope.gridweek,
      width: '14%'
    }, 
    {
      name: 'M',
      enableCellEdit: true,
      displayName: 'M',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right cBlue',
      headerCellClass: 'text-center bGreen',
      width: '8%'
    }, 
    {
      name: 'T',
      enableCellEdit: true,
      displayName: 'T',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right cBlue',
      headerCellClass: 'text-center bGreen',
      width: '8%'
    }, 
    {
      name: 'W',
      enableCellEdit: true,
      displayName: 'W',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right cBlue',
      headerCellClass: 'text-center bGreen',
      width: '8%'
    },
    {
      name: 'H',
      enableCellEdit: true,
      displayName: 'H',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right cBlue',
      headerCellClass: 'text-center bGreen',
      width: '8%'
    },
    {
      name: 'F',
      enableCellEdit: true,
      displayName: 'F',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right cBlue',
      headerCellClass: 'text-center bGreen',
      width: '8%'
    },
    {
      field: 'total',
      enableCellEdit: false,
      displayName: 'Total',
      enableColumnMenu: false,
      type: 'number',
      cellFilter: 'number:1',
      cellClass: 'text-right',
      headerCellClass: 'text-center bGreen',
      cellTemplate: 'total.tmpl.html',
      width: '10%'
    }
  ];

  $scope.msg = {};

  $scope.gridOpts.onRegisterApi = function(gridApi) {
    //set gridApi on scope
    $scope.gridApi = gridApi;
    gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
      $scope.msg.lastCellEdited = 'edited row id:' + rowEntity.id + ' Column:' + colDef.name + ' newValue:' + newValue + ' oldValue:' + oldValue;
      $scope.$apply();
    });
  };
}])

.filter('mapStatus', function() {
  var statusHash = {
    1: 'Full Time',
    2: 'Part Time'
  };

  return function(input) {
    if (!input) {
      return '';
    } else {
      return statusHash[input];
    }
  };
});

3 个答案:

答案 0 :(得分:3)

我在范围内创建了一个脏标志:

$scope.dirty = false;

我更新了监控版本的功能:

gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
  $scope.$apply(function(scope) {
    scope.dirty = true;
  });
});

请参阅plunkr:http://plnkr.co/edit/bSTXqp7wzLDL74rN3PII?p=preview

答案 1 :(得分:2)

尝试在数据集顶部添加一个薄层以跟踪记录脏状态。

var records = [];
angular.forEach(dataset, function (rawdata) {
    var record = {};
    //Track changed attrs, 
    //keys are the changed properties and 
    //values are an array of values [origValue, newValue].
    record.changedAttrs = {};

    //record dirty status
    Object.defineProperty(record, 'isDirty', {
        get: function () {
            return Object.getOwnPropertyNames(record.changedAttrs).length > 0; 
        }
    }); 

    angular.forEach(rawdata, function (value, key) {
        Object.defineProperty(record, key, {
            get: function () {
                return rawdata[key];  
            },

            set: function (value) {
                var origValue = record.changedAttrs[key] ? 
                    record.changedAttrs[key][0] : rawdata[key];

                if(value !== origValue) {
                    record.changedAttrs[key] = [origValue, value];
                } else {
                    delete record.changedAttrs[key];  
                }
                rawdata[key] = value;
            }
        })      
    });
    records.push(record);  
}); 

这是plunker。提供自定义行模板和额外的css行,当行变脏时,行bg颜色将变为黄色。

rowTemplate: '<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" ' + 
'ui-grid-one-bind-id-grid="rowRenderIndex + \'-\' + col.uid + \'-cell\'" ' + 
'class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader , \'row-dirty\': row.entity.isDirty}" ' + 
'role="{{col.isRowHeader ? \'rowheader\' : \'gridcell\'}}" ui-grid-cell></div>'

CSS

.ui-grid-cell.row-dirty {
    background-color: yellow !important;
}

答案 2 :(得分:0)

除了merlins的答案。 他的css风格对我不起作用。我做的是:

.ui-grid-row-dirty div {
    background-color: yellow !important;
}

将每个单元格(在行内)bg颜色设置为黄色。