【问题标题】:Angular ui-Grid Splice doesn't work with arrayAngular ui-Grid Splice 不适用于数组
【发布时间】:2016-02-19 07:26:56
【问题描述】:

我有一个 ui-grid,我试图用它来处理批量操作。操作完成后,应从网格中删除项目。问题是拼接只适用于其他所有记录。其余代码按预期工作,但不是拼接。在我按 F5 刷新页面之前,所有其他记录都保留在网格上(后端函数实际上从数据库中删除了行 - 我使用 splice 来更快地查看正确数据,而无需在数据库过程中刷新网格数据完成)。

这是我的控制器代码:

  $scope.gridOptions = {
        columnDefs: [
            {
                field: 'dteDateReleaseRequestedByCompany', displayName: 'Requested Date'
            },

      {
          field: 'vchCompanyName', displayName: 'Company Name',
          cellTemplate: '<div style="text-decoration:underline;color:blue;text-align:left;cursor:pointer" ng-click="grid.appScope.rowClick(row)">{{COL_FIELD}}</div>'
      },
      {
          field: 'CompanyID', width: 110, displayName: 'Company ID', visible:false
      },
      { field: 'vchOprCity', displayName: 'City' },
      { field: 'vchOprStateVchID', displayName: 'State' },
      {
          field: 'dteExpiresWithGracePeriod', displayName: 'Subscription', headerCellClass: 'center',
          cellTemplate: '<div style="text-align:center"><span ng-bind-html="row.entity[col.field] | getSubscription | trustedhtml"></span></div>'
      },
      {
          field: 'Action', displayName: 'Release Action', 
          cellTemplate: '<div class="btn-group" ng-init="row.entity.Action=0"><input ng-model="row.entity.Action" type="radio" value="0" style="width:20px">&nbsp;None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input ng-model="row.entity.Action" type="radio" value="1" style="width:20px">&nbsp;Accept&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input ng-model="row.entity.Action" type="radio" value="2" style="width:20px">&nbsp;Decline</div>'

      },

        ],
        showGridFooter: false,
        //enableFiltering: true,
        enableSorting: false,
        paginationPageSizes: [20, 40, 60],
        paginationPageSize: 20,
        enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
        enableGridMenu: true,
        exporterCsvFilename: 'PendingReleases.csv',
        exporterPdfDefaultStyle: { fontSize: 9 },
        exporterPdfTableStyle: { margin: [10, 10, 10, 10] },
        exporterPdfTableHeaderStyle: { fontSize: 10, bold: true, italics: true, color: 'red' },
        exporterPdfHeader: { text: "Pending Release Requests", style: 'headerStyle' },
        exporterPdfFooter: function (currentPage, pageCount) {
            return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
        },
        exporterPdfCustomFormatter: function (docDefinition) {
            docDefinition.styles.headerStyle = { fontSize: 22, bold: true, alignment: 'center' };
            docDefinition.styles.footerStyle = { fontSize: 10, bold: true, alignment: 'center' };
            return docDefinition;
        },
        exporterPdfOrientation: 'landscape',
        exporterPdfPageSize: 'LETTER',
        exporterPdfMaxGridWidth: 500,
        exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
        onRegisterApi: function (gridApi) {
            $scope.gridApi = gridApi;

        }
    };

  $scope.process = function () {
        for (i = 0; i < $scope.gridOptions.data.length; i++)
        {
            var id = $scope.gridApi.grid.renderContainers.body.visibleRowCache[i].entity.CompanyID;
            var action = $scope.gridApi.grid.renderContainers.body.visibleRowCache[i].entity.Action;
            var index = i;

            if(action ==1)
            {
                $scope.gridOptions.data.splice(index, 1);

                accept(id, index);
            }
            if(action == 2)
            {
                $scope.gridOptions.data.splice(index, 1);

                decline(id, index);

            }

        }


    };

    function accept(id, index) {
        contractorService.acceptRelease(id);

    };
    function decline(id, index) {
        contractorService.declineRelease(id);

    };

这是我的 HTML:

@{
    ViewBag.Title = "ManagePendingReleases";
    Layout = "~/Views/Shared/_Layout.cshtml";

}
<script src="~/Scripts/app/Contractor/ContractorCtrl.js"></script>
<script src="~/Scripts/app/Contractor/contractorService.js"></script>
<style>
    .ui-grid-header-cell {
  position: relative;
  box-sizing: border-box;
  color: black;
  background-color: #cfe7f1;
  border-right: 1px solid;
  border-color: #cfe7f1;
  display: table-cell;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  width: 0;
}
</style>
<div ng-app="myModule" ng-controller="ContractorCtrl">
    <div class="panel panel-primary">
        <div class="panel-heading" >Manage Pending Releases</div>
        <div class="panel-body" style="padding:0px">
            <div ui-grid="gridOptions" class="grid" ng-style="{height: (gridOptions.data.length*30)+32+'px'}" ui-grid-exporter ui-grid-auto-resize></div>
        </div>

    </div>
<div class="pull-right">
    <button type="button" class="btn btn-primary" ng-click="process()">Process Actions</button>
</div>
</div>

这是我的网格的样子:

当单击 Process Actions 按钮时,它应该遍历行并查找应该在数据库中的每条记录上发生的操作。 当我单步执行代码时,看起来拼接适用于每条记录,但其他所有记录都保留在网格上。谁能告诉我为什么会出现这种行为?

非常感谢任何帮助!

【问题讨论】:

  • 需要所有相关代码来了解发生了什么,请添加它。
  • 试试这个 $scope.gridOptions.data = $scope.gridOptions.data.splice(index, 1);
  • @EmirMarques splice 更改原始数组,所以没关系。
  • @vinayakj 对,但是角度会产生这个问题
  • @EmirMarques splice 是纯 javascript API,为什么 Angular 的对象与 javascript 对象有任何不同。

标签: javascript angularjs angular-ui-grid


【解决方案1】:

看看这个例子。注意如何排除。索引的对象是通过一个indexOf获得的

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

app.controller('MainCtrl', ['$scope', '$log', function($scope, $log) {

  $scope.deleteRow = function(row) {
    var index = $scope.gridOptions.data.indexOf(row.entity);
    $scope.gridOptions.data.splice(index, 1);
  };

  $scope.gridOptions = {};

  $scope.gridOptions.columnDefs = [{
    name: 'firstName'
  }, {
    name: 'lastName'
  }, {
    name: 'Delete',
    cellTemplate: '<button class="btn primary" ng-click="grid.appScope.deleteRow(row)">Delete</button>'
  }];

  $scope.gridOptions.data = [{
    "firstName": "Cox",
    "lastName": "Carney",
    "company": "Enormo",
    "employed": true
  }, {
    "firstName": "Lorraine",
    "lastName": "Wise",
    "company": "Comveyer",
    "employed": false
  }, {
    "firstName": "Nancy",
    "lastName": "Waters",
    "company": "Fuelton",
    "employed": false
  }];

}]);
<!doctype html>
<html ng-app="app">
  <head>
    <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>
    <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">
  <div ui-grid="gridOptions" class="grid"></div>
</div>


    <script src="app.js"></script>
  </body>
</html>

【讨论】:

  • 是的,但该示例是在特定行的点击事件中传入行对象。我没有传入行对象,因为我正在一次处理所有行。
【解决方案2】:

您在for 循环中使用数组的length,您正在执行splice,这反过来又减少了您使用index 删除项目,但splice 正在减少数组,所以index也需要改一下。

所以最接近的合理答案是,使用delete 而不是拼接,因为delete 不会改变index

delete $scope.gridOptions.data[index]

代替

$scope.gridOptions.data.splice(index, 1);

【讨论】:

  • 谢谢!完美运行!
猜你喜欢
  • 1970-01-01
  • 2017-04-08
  • 2014-02-23
  • 2023-03-11
  • 2019-07-25
  • 2017-02-26
  • 1970-01-01
  • 2019-04-12
  • 2019-09-15
相关资源
最近更新 更多