原文:

下载代码示例

这两种方法各有利弊。

Ext JS 还提供预定义控件,以简化 Web 应用程序 UI 的创建过程。

虽然将 Ext JS 与 Web 窗体开发集成起来比较困难(这是由于抽象层导致的;为了提供有状态的基于控件的模型,抽象层将封装 Web 的请求-响应特性),但您可以使用 ASP.NET MVC 框架,该框架使您能够在同一应用程序中同时利用 Microsoft .NET Framework 和 Ext JS。

在本文中,我将提供之前没有找到的教程,逐步介绍如何使用可从后端数据库读取并可向后端数据库写入的 ASP.NET MVC 和 Ext JS 来开发实际的 Web 解决方案。

Ext JS 窗体基础知识

sencha.com/products/license.php 以了解详细信息。

(还有一个调试版本可以帮助您更加轻松地找到错误。)依赖项、文档和示例代码都包含在下载的文件中。

resources 文件夹包含依赖项,如 CSS 和图像。

要正确使用 Ext JS,您还需要在您的页面中添加三个关键文件引用:

  1. ext-3.2.1/adapter/ext/ext-base.js
  2. ext-3.2.1/ext-all.js
  3. ext-3.2.1/resources/css/ext-all.css

ext-all.js 包含小组件定义,ext-all.css 包含小组件的样式表。

页面的开始部分包含以下几行代码,这几行代码链接着成功开发 Ext JS 解决方案所需的文件(我还在 JavaScript 模块中包含了 Ext JS 下载文件中的一些示例小组件):

  1. <link rel="stylesheet" type="text/css"
  2. href="ext-3.2.1/resources/css/ext-all.css" />
  3. <script type="text/javascript" language="javascript"
  4. src="ext-3.2.1/adapter/ext/ext-base.js"></script>
  5. <script type="text/javascript" language="javascript"
  6. src="ext-3.2.1/ext-all.js"></script>
  7. <script type="text/javascript" language="javascript"
  8. src="extjs-example.js"></script>

我在文件正文中插入了一个 div 元素,以呈现主 Ext JS 窗体:


          
        

ns、Ext.BLANK_IMAGE_URL 和 Ext.onReady 语句:

  1. Ext.
  2. ns('formextjs.tutorial');
  3. Ext.BLANK_IMAGE_URL = 'ext-3.2.1/resources/images/default/s.gif';
  4. formextjs.tutorial.FormTutorial = {
  5. ...
  6. }
  7. Ext.onReady(formextjs.tutorial.FormTutorial.init,
  8. formextjs.tutorial.FormTutorial);

ns 语句使您能够按照逻辑组织命名空间中的代码,以避免命名冲突和作用域问题。

它称为空白区域图片(1x1 像素的透明图像),主要用于生成空白区域和放置图标及分隔符。

至于 extjs-example.js,下面就是该脚本:

  1. formextjs.tutorial.FormTutorial = {
  2. init: function () {
  3. this.form = new Ext.FormPanel({
  4. title: 'Getting started form',
  5. renderTo: 'frame',
  6. width: 400,
  7. url: 'remoteurl',
  8. defaults: { xtype: 'textfield' },
  9. bodyStyle: 'padding: 10px',
  10. html: 'This form is empty!'
  11. });
  12. }
  13. }

最后,html 属性指定作为默认输出的文本(带有任何 HTML 格式)。

要添加字段,您需要使用 items 属性替换 html 属性:

  1. items: [ nameTextField, ageNumberField ]

首先要添加的两个项是文本字段和数值字段:


          var nameTextField = new Ext.form.TextField({
  fieldLabel: 'Name',
  emptyText: 'Please, enter a name',
  name: 'name'
});
var ageNumberField = new Ext.form.NumberField({
  fieldLabel: 'Age',
  value: '25',
  name: 'age'
});
        

value 属性是控件的默认值。

声明控件的另外一种方法是在进行中声明:

  1. items: [
  2. { fieldLabel: 'Name', emptyText: 'Please, enter a name', name: 'name' },
  3. { xtype: 'numberfield', fieldLabel: 'Age', value: '25', name: 'age' }
  4. ]

如您所见,对于 Name 字段,您不必指定类型,因为它是从窗体的默认属性获得的。

我将在窗体中添加一些附加元素,结果如图 1 所示。

使用 ASP.NET MVC 和 Ext JS 构建以数据为中心的 Web 应用程序

图 1 完成的窗体

您需要添加一个按钮,以处理提交过程并向用户显示结果,如图 2 所示。

图 2 窗体按钮

  1. buttons: [{
  2. text: 'Save',
  3. handler: function () {
  4. form.getForm().submit({
  5. success: function (form, action) {
  6. Ext.Msg.alert('Success', 'ok');
  7. },
  8. failure: function (form, action) {
  9. Ext.Msg.alert('Failure', action.result.error);
  10. }
  11. });
  12. }
  13. },
  14. {
  15. text: 'Reset',
  16. handler: function () {
  17. form.getForm().reset();
  18. }
  19. }]

Reset 按钮处理程序重置窗体上的字段值。

例如,下面是窗体的 Name 字段:

  1. { fieldLabel: 'Name', emptyText: 'Please, enter a name', name: 'name', allowBlank: false }

如果未在 Name 和 Age 字段中输入任何数据,当您运行应用程序并单击 Save 按钮时,您会收到一条错误消息,并且必填字段下会出现红色下划线。

要自定义针对这些字段的错误消息,在 Ext.onReady 函数下添加下面这行代码:

  1. Ext.QuickTips.init();

现在,当用户将鼠标指针移动到字段上方时,就会显示一个提示框,其中包含用于说明错误的消息。

您可以在代码下载中查看此验证的详细信息。

构建 Web 应用程序

我接下来要解决的情况是在人力资源管理系统中添加一个员工。

department 字段是一个用于从中选择部门的部门列表。

后端数据库是 Microsoft SQL Server 2008。

首先打开 Visual Studio 2010,使用 ASP.NET MVC 2 Web 应用程序模板创建一个新项目。

图 3 显示了我是如何创建 Human Resources 数据库和基础表及约束的。

图 3 创建 Human Resources 数据库

  1. create table department(
  2. deptno varchar(20) primary key,
  3. deptname varchar(50) not null,
  4. location varchar(50)
  5. );
  6. create unique index undx_department_deptname on department(deptname);
  7. insert into department
  8. values('HQ-200','Headquarter-NY','New York');
  9. insert into department
  10. values('HR-200','Human Resources-NY','New York');
  11. insert into department
  12. values('OP-200','Operations-NY','New York');
  13. insert into department
  14. values('SL-200','Sales-NY','New York');
  15. insert into department
  16. values('HR-300','Human Resources-MD','Maryland');
  17. insert into department
  18. values('OP-300','Operations-MD','Maryland');
  19. insert into department
  20. values('SL-300','Sales-MD','Maryland');
  21. create table employee(
  22. empno varchar(20) primary key,
  23. fullname varchar(50) not null,
  24. address varchar(120),
  25. age int,
  26. salary numeric(8,2) not null,
  27. deptno varchar(20) not null,
  28. constraint fk_employee_department_belong_rltn foreign key(deptno)
  29. references department(deptno)
  30. );
  31. create unique index undx_employee_fullname on employee(fullname);

在本例中,您仅需要实现创建操作:

  1. public class EmployeeRepository {
  2. private HumanResourcesDataContext _ctxHumanResources =
  3. new HumanResourcesDataContext();
  4. public void Create(employee employee) {
  5. this._ctxHumanResources.employees.InsertOnSubmit(employee);
  6. this._ctxHumanResources.SubmitChanges();
  7. }
  8. }

同样,在这个简单的示例中,您仅需要实现读取操作以查找部门列表:

  1. public class DepartmentRepository {
  2. private HumanResourcesDataContext _ctxHumanResources =
  3. new HumanResourcesDataContext();
  4. public IQueryable<department> FindAll() {
  5. return from dept in this._ctxHumanResources.departments
  6. orderby dept.deptname
  7. select dept;
  8. }
  9. }

我使用 HumanResourcesController 作为控制器名称。

Ext JS 表示层

对于此解决方案,您仅需要导入 ext-all.js 和 \adapter 及 \resources 文件夹。

转到 Site.Master 页面,在 head 元素中添加对 Ext JS 文件的引用,并添加 <asp:ContentPlaceHolder> 标记元素作为各个页面的自定义 JavaScript 和 CSS 代码的容器,如图 4 所示。

图 4 Site.Master

  1. <head runat="server">
  2. <title><asp:ContentPlaceHolder ID="TitleContent"
  3. runat="server" /></title>
  4. <link href="http://www.cnblogs.com/Content/Site.css" rel="stylesheet"
  5. type="text/css" />
  6. <!-- Include the Ext JS framework -->
  7. <link href="<%= Url.Content("~/Scripts/ext-3.2.1/resources/css/ext-all.css") %>"
  8. rel="stylesheet" type="text/css" />
  9. <script type="text/javascript"
  10. src="<%= Url.Content("~/Scripts/ext-3.2.1/adapter/ext/ext-base.js") %>">
  11. </script>
  12. <script type="text/javascript"
  13. src="<%= Url.Content("~/Scripts/ext-3.2.1/ext-all.js") %>">
  14. </script>
  15. <!-- Placeholder for custom JS and CSS and JS files
  16. for each page -->
  17. <asp:ContentPlaceHolder ID="Scripts" runat="server" />
  18. </head>

单击 Add View 对话框中的 Add 按钮。

然后将该引用添加到 employee_form.js 文件中,并将 div 元素添加到 Index.aspx 视图中(请参见图 5)。

图 5 添加员工窗体

  1. <%@ Page Title="" Language="C#"
  2. MasterPageFile="~/Views/Shared/Site.Master"
  3. Inherits="System.Web.Mvc.ViewPage" %>
  4. <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
  5. runat="server">
  6. Index
  7. </asp:Content>
  8. <asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
  9. runat="server">
  10. <h2>Add a New Employee</h2>
  11. <div id="employeeform"></div>
  12. </asp:Content>
  13. <asp:Content ID="Content3" ContentPlaceHolderID="Scripts"
  14. runat="server">
  15. <script type="text/javascript"
  16. src="<%= Url.Content("~/Scripts/employee_form.js") %>">
  17. </script>
  18. </asp:Content>

第一步是定义 Ext.data.JsonStore 类的一个实例,以获取部门列表:

  1. var departmentStore = new Ext.data.JsonStore({
  2. url: 'humanresources/departments',
  3. root: 'departments',
  4. fields: ['deptno', 'deptname']
  5. });

这些属性均为自描述性属性:

  1. var form = new Ext.FormPanel({
  2. title: 'Add Employee Form',
  3. renderTo: 'employeeform',
  4. width: 400,
  5. url: 'humanresources/addemployee',
  6. defaults: { xtype: 'textfield' },
  7. bodyStyle: 'padding: 10px',

此方法也可通过 HTTP POST 动词进行访问。

最后,部门编号字段是一个是从部门列表中选择的标识符字符串。

图 6 窗体字段小组件

  1. items: [
  2. { fieldLabel: 'Employee ID', name: 'empno', allowBlank: false },
  3. { fieldLabel: 'Fullname', name: 'fullname', allowBlank: false },
  4. { xtype: 'textarea', fieldLabel: 'Address', name: 'address',
  5. multiline: true },
  6. { xtype: 'numberfield', fieldLabel: 'Age', name: 'age' },
  7. { xtype: 'numberfield', fieldLabel: 'Salary', name: 'salary',
  8. allowBlank: false },
  9. { xtype: 'combo', fieldLabel: 'Department', name: 'deptno',
  10. store: departmentStore, hiddenName: 'deptno',
  11. displayField: 'deptname', valueField: 'deptno', typeAhead: true,
  12. mode: 'remote', forceSelection: true, triggerAction: 'all',
  13. emptyText: 'Please, select a department...', editable: false }
  14. ],

这里的配置和图 2 中的配置相似,但文本属性的值为“Add”。

有关此文件的完整源代码列表,请参见代码下载。)

现在让我们转到 HumanResourceController,并执行相应的操作方法,如图 7 所示。

图 7 HumanResourceController

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using HumanResources_ExtJS_ASPNETMVC.Models;
  7. namespace HumanResources_ExtJSASPNETMVC.Models.BusinessObjects {
  8. public class HumanResourcesController : Controller {
  9. DepartmentRepository _repoDepartment = new DepartmentRepository();
  10. EmployeeRepository _repoEmployee = new EmployeeRepository();
  11. // GET: /HumanResources/
  12. public ActionResult Index() {
  13. return View();
  14. }
  15. // POST: /HumanResource/Departments
  16. [HttpPost]
  17. public ActionResult Departments() {
  18. var arrDepartment = this._repoDepartment.FindAll();
  19. var results = (new {
  20. departments = arrDepartment
  21. });
  22. return Json(results);
  23. }
  24. // POST: /HumanResource/AddEmployee
  25. [HttpPost]
  26. public ActionResult AddEmployee(employee employee) {
  27. string strResponse = String.Empty;
  28. try {
  29. this._repoEmployee.Create(employee);
  30. strResponse = "{success: true}";
  31. }
  32. catch {
  33. strResponse = "{success: false, error: \"An error occurred\"}";
  34. }
  35. return Content(strResponse);
  36. }
  37. }
  38. }

大功告成!

您还会看到在数据库的 dbo.employee 表中插入的行。

使用 ASP.NET MVC 和 Ext JS 构建以数据为中心的 Web 应用程序

图 8 运行应用程序

这些简单的构造块使构建以数据为中心的基本 RIA 变得快速而简单。

相关文章:

  • 2022-12-23
  • 2021-09-07
  • 2022-12-23
  • 2022-01-09
  • 2021-12-13
  • 2022-12-23
  • 2021-08-05
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-17
  • 2021-05-01
  • 2021-12-04
  • 2021-12-05
相关资源
相似解决方案