65.9K
CodeProject 正在变化。 阅读更多。
Home

AngularJS 中的 GridView 批量编辑

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (25投票s)

2014 年 10 月 15 日

CPOL

5分钟阅读

viewsIcon

57304

downloadIcon

2338

本文为您提供了使用 Angular.js 实现批量编辑(GridView/Repeater 中的内联编辑)的简化方法。

引言

GridView 中编辑数据是当今常见的场景之一。借助 AngularJS 的双向数据绑定功能,编写相对而言被称为复杂操作的代码,如 GridView 中的批量编辑,变得异常简单。本文提供了多种方法,说明您如何只需几行代码即可在 GridView 中实现批量编辑。我还提供了将更新的 Grid 数据通过 WebAPI 发布到服务器以保存到数据库的示例。

请注意,如果您正在寻找内置的 AngularJS GridView 工具,您会发现许多功能丰富的工具。本文提供了一种原生方法,只需几行代码,就能帮助您满足自定义需求。同样的方法也适用于任何内联编辑。还提供了一个非表格 Repeater 项内联编辑的示例。

本文假设您了解 AngularJS 的基础知识。

下面是应用程序中基本批量编辑的屏幕截图

下面的屏幕截图显示了批量编辑的第二种方法

工作原理

在 AngularJS 中实现批量编辑可以分为 3 个简单步骤

  1. 通过控制器中的 API 从服务器获取 Grid 数据
  2. 将数据填充到表格行中相应的控件,而不是直接填充到表格单元格
  3. 点击提交时,只需将数据提交到服务器

步骤 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 而不是 trtd。下面是相同内容的输出

关于代码

在本节中,我详细介绍了一些代码的编写方式。这将有助于那些刚接触 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日:第一个版本
© . All rights reserved.