AngularJS 中的 GridView 批量编辑






4.81/5 (25投票s)
本文为您提供了使用 Angular.js 实现批量编辑(GridView/Repeater 中的内联编辑)的简化方法。
引言
在 GridView
中编辑数据是当今常见的场景之一。借助 AngularJS 的双向数据绑定功能,编写相对而言被称为复杂操作的代码,如 GridView
中的批量编辑,变得异常简单。本文提供了多种方法,说明您如何只需几行代码即可在 GridView
中实现批量编辑。我还提供了将更新的 Grid 数据通过 WebAPI 发布到服务器以保存到数据库的示例。
请注意,如果您正在寻找内置的 AngularJS GridView 工具,您会发现许多功能丰富的工具。本文提供了一种原生方法,只需几行代码,就能帮助您满足自定义需求。同样的方法也适用于任何内联编辑。还提供了一个非表格 Repeater 项内联编辑的示例。
本文假设您了解 AngularJS 的基础知识。
下面是应用程序中基本批量编辑的屏幕截图
下面的屏幕截图显示了批量编辑的第二种方法
工作原理
在 AngularJS 中实现批量编辑可以分为 3 个简单步骤
- 通过控制器中的 API 从服务器获取 Grid 数据
- 将数据填充到表格行中相应的控件,而不是直接填充到表格单元格
- 点击提交时,只需将数据提交到服务器
步骤 1
从服务器获取数据很容易。您只需使用 $http
/resource 并将检索到的数据分配给您的作用域变量即可。
第二步
如果您了解 AngularJS 和 HTML,创建表格/Grid 非常简单。只需创建一个 table
元素,并使用 ng-repeat
来填充每行的相应元素。如果您不想使用 table
,也可以选择任何其他模板。
请看下面的示例,模型/数据直接绑定到 HTML 控件。AngularJS 的优点在于,一旦您更改 HTML 控件中的数据,模型就会自动更新。
<table id="employeeEditTable" class="table table-bordered batch-edit">
<colgroup>
<col width="60" />
<col width="140" />
<col width="300" />
<col width="100" />
<col width="100" />
<col width="100" />
</colgroup>
<tr>
<th>S. No.</th>
<th>Name</th>
<th>Address</th>
<th>Date of Birth</th>
<th>Salary</th>
<th>Country</th>
</tr>
<tr ng-repeat="employee in employees">
<td>{{$index + 1}}.</td>
<td><input type="text" ng-model="employee.Name" /></td>
<td><input type="text" ng-model="employee.Address" /></td>
<td>
<input type="text" ng-model="employee.BirthDate"
name="date" bs-datepicker />
</td>
<td class="text-right">
<input type="number" class="text-right" ng-model="employee.Salary" />
</td>
<td>
<select ng-options="c.Name for c in countries"
ng-model="employee.Country"
ng-init="setDropDown(employee);"
ng-change="employee.CountryId = employee.Country.Id"></select>
</td>
</tr>
</table>
在某些场景下,您可能希望控件仅在编辑时显示。这使得您在显示时可以使用不同的格式。为了实现这一点,我在 Grid 中为每个文本设置了两个元素。一个在显示数据时出现,另一个在编辑时出现。为了实现这一点,我只是使用了 ng-show
指令,并使这两个控件互斥,如下所示:
- 显示控件:
ng-show="!employee.edit.Name"
- 编辑控件:
ng-show="employee.edit.Name"
以下代码演示了此方法
<tr ng-repeat="employee in employees">
<td>{{$index + 1}}.</td>
<td>
<div ng-show="!employee.edit.Name"
ng-dblclick="employee.edit.Name =
!employee.edit.Name">{{employee.Name}}</div>
<input type="text" ng-show="employee.edit.Name"
ng-blur="employee.edit.Name = !employee.edit.Name"
ng-model="employee.Name" />
</td>
<td>
<div ng-show="!employee.edit.Address"
ng-dblclick="employee.edit.Address =
!employee.edit.Address">{{employee.Address}}</div>
<input type="text" ng-show="employee.edit.Address"
ng-blur="employee.edit.Address = !employee.edit.Address"
ng-model="employee.Address" />
</td>
<td>
<div ng-show="!employee.edit.BirthDate"
ng-dblclick="employee.edit.BirthDate =
!employee.edit.BirthDate">{{employee.BirthDate |
date:'dd MMM, yyyy'}}</div>
<input type="text" ng-show="employee.edit.BirthDate"
ng-blur="employee.edit.BirthDate = !employee.edit.BirthDate"
ng-model="employee.BirthDate" name="date" bs-datepicker />
</td>
<td class="text-right">
<div ng-show="!employee.edit.Salary"
ng-dblclick="employee.edit.Salary = !employee.edit.Salary">
{{employee.Salary | currency}}</div>
<input type="number" ng-show="employee.edit.Salary"
ng-blur="employee.edit.Salary = !employee.edit.Salary"
ng-model="employee.Salary" />
</td>
<td>
<div ng-show="!employee.edit.Country"
ng-dblclick="employee.edit.Country =
!employee.edit.Country">{{employee.Country.Name}}</div>
<select ng-options="c.Name for c in countries"
ng-show="employee.edit.Country"
ng-blur="employee.edit.Country = !employee.edit.Country"
ng-model="employee.Country" ng-init="setDropDown(employee);"
ng-change="employee.CountryId = employee.Country.Id"></select>
</td>
</tr>
您可以根据任何事件来切换此显示。在示例中,它是在双击事件中切换的。
步骤 3
当 HTML 控件中的数据发生更改时,模型会自动更新。因此,在此步骤中,您无需担心从控件收集数据。只需通过 API 将模型发送回服务器即可。在我的示例中,我使用了 $http
将更新后的模型发布回 WebAPI。
非表格 Repeater 项的批量编辑
在许多场景中,我们需要将项目列表显示为一个块,该块会为每个项目重复。在这种情况下,gridview
可能不是您批量编辑需求的最佳选择。下面是一个示例,说明如何用几行代码轻松实现这一点
<div class="rpt-item pull-left col-md-4" ng-class="{'bg-gray': $index % 2 != 0}"
ng-repeat="employee in employees">
<h4>
{{$index + 1}}.
<span ng-show="!employee.edit.Name" ng-dblclick="employee.edit.Name =
!employee.edit.Name; $(this).next().focus();">{{employee.Name}}</span>
<input type="text" ng-show="employee.edit.Name" ng-blur="employee.edit.Name =
!employee.edit.Name"
ng-model="employee.Name" />
</h4>
<div ng-show="!employee.edit.BirthDate" ng-dblclick="employee.edit.BirthDate =
!employee.edit.BirthDate">
<strong>DOB:</strong> {{employee.BirthDate | date: 'dd MMM, yyyy'}}
</div>
<input type="text" ng-show="employee.edit.BirthDate"
ng-blur="employee.edit.BirthDate = !employee.edit.BirthDate"
ng-model="employee.BirthDate" name="date" bs-datepicker="bs-datepicker" />
<div ng-show="!employee.edit.Salary" ng-dblclick="employee.edit.Salary =
!employee.edit.Salary">
<strong>Salary:</strong> {{employee.Salary | currency}}
</div>
<input type="number" ng-show="employee.edit.Salary"
ng-blur="employee.edit.Salary = !employee.edit.Salary"
ng-model="employee.Salary" />
<div ng-show="!employee.edit.Address" ng-dblclick="employee.edit.Address =
!employee.edit.Address">
<strong>Address:</strong> {{employee.Address}}
</div>
<input type="text" ng-show="employee.edit.Address"
ng-blur="employee.edit.Address = !employee.edit.Address"
ng-model="employee.Address" />
<div ng-show="!employee.edit.Country" ng-dblclick="employee.edit.Country =
!employee.edit.Country">
<strong>Country:</strong> {{employee.Country.Name}}
</div>
<select ng-options="c.Name for c in countries" ng-show="employee.edit.Country"
ng-blur="employee.edit.Country = !employee.edit.Country"
ng-model="employee.Country" ng-init="setDropDown(employee);"
ng-change="employee.CountryId = employee.Country.Id"></select>
</div>
这里的批量编辑方法与表格批量编辑非常相似。唯一的区别是,这里使用了 div
而不是 tr
和 td
。下面是相同内容的输出
关于代码
在本节中,我详细介绍了一些代码的编写方式。这将有助于那些刚接触 AngularJS 的人。
CSS 部分
使用原生方法创建 Grid 的最大优势在于,您可以随心所欲地自定义。在我们的示例中,表格单元格内有一个 textbox
、下拉菜单和其他控件。为了美观,边框被移除,宽度设置为 100%。
.batch-edit input, .batch-edit select{
margin:-4px;
border:none;
width:100%;
}
控制器
对于所有编辑页面,都使用了一个名为 employeeEditCtrl
的控制器,并关联了多个视图。该控制器仅包含三个主要函数。一个用于从 WebAPI 填充 Employee
和相关数据。另一个根据检索到的数据设置下拉列表的值。第三个用于在单击提交按钮时提交数据。有关详细信息,请参阅 employeeEditCtrl.js 文件。
杂项
我使用了 factory 来通过 $http
检索数据,但您可以根据自己的需要以任何方式检索数据。angular-ui-router.js 用于路由和导航。为了简单起见,我没有使用任何数据库。使用了 Mock DB 来为 UI 提供数据。
关注点
本文还作为使用 AngularJS 在 Grid 中显示数据的示例。此外,代码还提供了如何使用 Angular UI 路由和在 AngularJS 中使用 date-picker
控件的示例。
未来考量
由于时间原因,我没有提供仅针对行的内联编辑示例。稍后,我还会添加一个编辑记录作为弹出窗口的示例。此外,在当前示例中,我只添加了最常用的编辑控件,如文本框、数字、日期时间选择器和下拉菜单。将来,我还会添加一些更复杂的控件。
历史
- 2014年10月15日:第一个版本