ERP俱乐部
ERP爱好者、ERP从业者互相交流、互相学习的乐园;我们的愿景是成为全球一流的中文ERP(Enterprise Resource Planning)交流平台
网站首页 论坛首页 搜索 用户列表 FAQ 注册 登录  
ERP俱乐部 -> Microsoft专栏 -> ASP.NET -> 微软MVC框架功力深厚:Web开发化繁为简
  微软MVC框架功力深厚:Web开发化繁为简
帖子发起人: 半神   发起时间: 2012-02-14 10:46 上午   回复数: 0
? 上一主题 下一主题 ?
楼主
  2012-02-14, 10:46 上午
半神 离线,最后访问时间: 2013/6/5 18:59:05 半神

发帖数前25位

超级管理员
职务: 超级管理员
80级
等级: 80级
注册: 2008年1月6日
区域: 华南
经验: 1,267
积分: 1,131
精华: 2
发贴: 590
排名: 26
Site AdministratorsGlobal ModeratorsSite ModeratorsSite Registered Users培训学员(MM学员服务区-北京200708班) 培训学员(FI学员服务区-深圳200805班) 每日发帖之星
微软MVC框架功力深厚:Web开发化繁为简
 
奥巴马说过,“如果我们总是试图等待他人来改变命运,那么这种改变是永远不会发生的,因为命运掌握在自己手中。”作为读者,无论您身怀何种政治信仰,改变无处不在。它不仅体现在政治,经济全球化,气候变暖,甚至是软件开发都产生了一系列深刻的变化。

  对于从事软件开发的您来说,改变不是一件坏事,反而是一件好事。毕竟,正是软件的日益变化才使得钞票流入了口袋,弄得你忙得不可开交,不是吗?当然,作为代价,作为工程师的你,必须能时刻适应这种变化的节奏,这不是件容易的事啊。

  本文的出发点,是带您熟悉并掌握一种新型的微软MVC框架。这种MVC框架融合了两大JavaScrip库JQuery与Knockout,以及一个标准数据交换格式JSON等多项技术。为便于您的理解,我们给出了一个经典的Web App样例的代码。

  关于示例程序

  本文的示例WebApp采用的是微软MVC ASP.NET框架的最新版本——MVC4。WebApp的名称为Order Entry,关联的数据库是著名的Northwind SQL-Server(创建数据库的脚本可在本文的代码区下载)。

  程序架构

   示例Web App的架构设计目标是:实现Model与MVC (Model-View-Controller)其余部分的分离。Web App只包含View与Controller两个组件,另一个组件Model则被移至应用服务(application service)层。应用服务层的底层实现技术之一是基于Windows Communication Foundation (WCF)框架的Web Service。这种设计模式特别适用于“不同前后端应用共享同一业务组件”的SOA架构。

  “点击按钮”的背后玄机

  您可能有所不知,简单的鼠标点击操作,背后其实暗藏玄机。事实上,示例Web App的大部分按钮点击操作均会触发若干的JQuery AJAX调用,并返回若干JSON对象。这些JSON对象包含:一或多个MVC Partial视图,一个View Model对象。

  轻量级Controller

   示例Web App的Controller均是轻量级的,除了在View与前面提及的应用服务层做转发操作或Middleman,什么都不做。换句话 说,Controller要做的仅仅是,接收来自View的用户表单数据,然后与某个View Model绑定。紧接着,Controller将View Model对象传递到应用服务层,并调用独立于MVC之外的业务组件,完成操作。待调用完成之后,Controller要做的即是,将View Model对象返回给View。

  轻量级Controller带来了程序的易于测试,重用性好,关注分离等诸多好处。

  面对MVC的诱惑,还不赶紧创建自己的DataGrid控件?

   作为本文的示例Web App,Northwind Order Entry的第一步是从一个data grid中选取一个customer。MVC兼容不同的data grid控件,例如Telerik, JQuery,及其它各种开源库。这些并不重要,重要的MVC框架内置一个称为Razor的强大View引擎,可以灵活自如地开发各种不同的网页。 Razor的特点是:实用、精准、轻量级。ASP.NET MVC工程通过Razor创建View,具有关注分离,易于测试,基于模式开发等一系列优点。

   说了这么多,您会不会按捺不住,跃跃欲试呢?来,弄上几个Data Grid吧。基本上,要创建一个data grid,只需要渲染一个HTML表格,注入一些JavaScript以及一些隐藏的HTML控件,就搞定啦。示例Web App使用的是一个用户自定义的Data Grid,支持数据的分页,排序,筛选。

  Customer Inquiry View – 分页,排序,选择

   加载Customer Inquiry View时,调用一个JavaScript函数CustomerInquiry 。CustomerInquiry 利用JQuery AJAX函数最终调用另一个MVC Controller函数。MVC Controller函数会返回一个Partial 视图,并将Data Grid控件渲染到页面。

<script language="javascript" type="text/javascript">

    
function CustomerInquiryRequest() {

        this.CurrentPageNumber;
        this.PageSize;
        this.CustomerID;
        this.CompanyName;    
        this.ContactName;
        this.SortDirection;
        this.SortExpression;

    };

    
function CustomerInquiry(currentPageNumber, sortExpression, sortDirection) {

        var url
= "/Orders/CustomerInquiry";

        var customerInquiryRequest
= new CustomerInquiryRequest();

        customerInquiryRequest.CustomerID
= $("#CustomerID").val();
        customerInquiryRequest.CompanyName
= $("#CompanyName").val();
        customerInquiryRequest.ContactName
= $("#ContactName").val();
        customerInquiryRequest.CurrentPageNumber
= currentPageNumber;
        customerInquiryRequest.SortDirection
= sortDirection;
        customerInquiryRequest.SortExpression
= sortExpression;
        customerInquiryRequest.PageSize
= 15;

        $.post(url, customerInquiryRequest,
function (data, textStatus) {
            CustomerInquiryComplete(data);
        });

    };

    
function CustomerInquiryComplete(result) {

        
if (result.ReturnStatus == true) {
            $(
"#CustomerResults").html(result.CustomerInquiryView);
            $(
"#MessageBox").html("");
        }
        
else {
            $(
"#MessageBox").html(result.MessageBoxView);
        }

    }  

</script>

       Customer Inquiry Controller函数

   Controller函数签名多种多样,其中之一是单独定义每一个函数参数。MVC框架按名称自动填充参数值。下面的Controller函数定义则采 取了完全不同的一种方法,即采用FormCollection 数组解析法。早在经典的ASP时代, Form Collection数组就已经成为了HTTP表单数据解析技术的基础。我们之所以采用Form Collection数组这种方法,是因为即便表单数据与Controller函数签名不完全匹配,MVC也总能解决问题。

/// <summary>        
/// Customer Inquiry        
/// </summary>          
/// <param name="postedFormData"></param>        
/// <returns></returns>
public ActionResult CustomerInquiry(FormCollection postedFormData)
{          
  
  CustomerApplicationService customerApplicationService
= new CustomerApplicationService();

  CustomerViewModel customerViewModel
= new CustomerViewModel();

  customerViewModel.PageSize
= Convert.ToInt32(postedFormData["PageSize"]);
  customerViewModel.SortExpression
= Convert.ToString(postedFormData["SortExpression"]);
  customerViewModel.SortDirection
= Convert.ToString(postedFormData["SortDirection"]);
  customerViewModel.CurrentPageNumber
= Convert.ToInt32(postedFormData["PageNumber"]);
  customerViewModel.Customer.CustomerID
= Convert.ToString(postedFormData["CustomerID"]);
  customerViewModel.Customer.CompanyName
= Convert.ToString(postedFormData["CompanyName"])
  customerViewModel.Customer.ContactName
= Convert.ToString(postedFormData["ContactName"]);

  customerViewModel
= customerApplicationService.CustomerInquiry(customerViewModel);

  return Json(
new
  {
    ReturnStatus
= customerViewModel.ReturnStatus,
    ViewModel
= customerViewModel,
    MessageBoxView
= RenderPartialView(this,"_MessageBox", customerViewModel),
    CustomerInquiryView
= RenderPartialView(this, "CustomerInquiryGrid", customerViewModel)
  });

}
View Model

  Controller函数Customer Inquiry 调用应用服务层,返回一个表示customer data的Customer View Model。MVC Model指的是一系列表示后端数据的类,而MVC View通常需要收集不同的后端数据,此时就有了View Model类的概念,方便View 获取所有Model信息。从这个角度将,View Model是一个front-end类,连接前端的UI与后端数据通信。

/// <summary>
/// Customer View Model
/// </summary>
public class CustomerViewModel : ViewInformation
{

public List<Customer> Customers;
public Customer Customer;
public int TotalCustomers { get; set; }

public CustomerViewModel()
{
Customer
= new Customer();
Customers
= new List<Customer>();
ReturnMessage
= new List<String>();
ValidationErrors
= new Hashtable();
TotalCustomers
= 0;
}

}

/// <summary>
/// Order View Model
/// </summary>
public class OrderViewModel : ViewInformation
{

public Orders Order;
public OrderDetails OrderDetail;
public List<Orders> Orders;
public List<OrdersCustomer> OrderCustomer;
public List<OrderDetailsProducts> OrderDetailsProducts;
public OrderDetailsProducts OrderLineItem;
public List<OrderDetails> OrderDetails;
public List<Shippers> Shippers;
public Customer Customer;
public int TotalOrders { get; set; }

public OrderViewModel()
{
Customer
= new Customer();
Order
= new Orders();
OrderDetail
= new OrderDetails();
Orders
= new List<Orders>();
OrderDetails
= new List<OrderDetails>();
OrderCustomer
= new List<OrdersCustomer>();
Shippers
= new List<Shippers>();
OrderDetailsProducts
= new List<OrderDetailsProducts>();
OrderLineItem
= new OrderDetailsProducts();
ReturnMessage
= new List<String>();
ValidationErrors
= new Hashtable();
TotalOrders
= 0;

}

}

  SQL-Server的数据分页

  从后端SQL的角度,要从数据路SQL-Server返回一页数据,可使用ROW_NUMBER OVER语法,配合Record的开始与结束游标。相比于因应用程序调用而返回大量的Recordset,SQL的效率要高许多。

SELECT * FROM (
SELECT (ROW_NUMBER() OVER (ORDER BY CompanyName ASC)) as record_number,
CustomerID, CompanyName, ContactName, ContactTitle, City, Region
FROM Customers ) Rows where record_number between
16 and 30

 

  强大的JSON与Partial View

  JSON (JavaScript Object Notation)是一个轻量级的数据交互格式。如上所述,Customer Inquiry Conroller函数调用应用服务层,以View Model的形式获取数据。

   Conroller函数返回给客户端页面的是一个JSON对象。此JSON对象既包含如上所述的View Model,也包含Partial View对应的Data Grid控件经过渲染产生的HTML。MVC的真正威力之处在于,能渲染Partial View的局部HTML片段。

  Partial View渲染小帮手

  ASP.NET MVC框架包含各种不同的Helper函数,可轻松实现在视图中渲染HTML,例如创建按钮,文本框,超链接,表单。Helper函数的使用方式有两种,一是扩展已有的MVC Helper方法,二是也可以根据业务需要,自己定制。

  这里,我们创建一个RenderPartialView Helper函数,调用Partial View并将调用结果以字符串的形式输出。之后,该字符串会被封装成一个JSON对象,供AJAX调用。该Helper函数调用Razor View Engine,在服务器端运行Partial View。当我们需要将HTML返回给AJAX调用时,这一点显得尤为适用。

public static string RenderPartialView(this Controller controller,
string viewName, object model)
{

if (string.IsNullOrEmpty(viewName))
return
null;

controller.ViewData.Model
= model;

using (var sw
= new StringWriter())
{

ViewEngineResult viewResult
=
ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);

var viewContext
= new ViewContext(controller.ControllerContext,
viewResult.View, controller.ViewData, controller.TempData, sw);

viewResult.View.Render(viewContext, sw);

return sw.GetStringBuilder().ToString();

}

}

  Partial View “Customer Inquiry Grid”

  View与Partial View内部均含有服务器/客户端代码。两者在外观上与使用感觉上,都有经典ASP功能的味道。下面的Customer Inquiry Grid Partial View仅包含服务器端代码,目的是渲染一个用户自定义的Data Grid。

@model NorthwindViewModel.CustomerViewModel
@using NorthwindWebApplication.Helpers;

@{

NorthwindDataGrid pagedDataGrid
= new NorthwindDataGrid("CustomerInquirGrid");

pagedDataGrid.Title
= "Customers";
pagedDataGrid.TotalPages
= Model.TotalPages;
pagedDataGrid.TotalRecords
= Model.TotalCustomers;
pagedDataGrid.CurrentPageNumber
= Model.CurrentPageNumber;
pagedDataGrid.SortDirection
= Model.SortDirection;
pagedDataGrid.SortExpression
= Model.SortExpression;
pagedDataGrid.RowSelectionFunction
= "CustomerSelected";
pagedDataGrid.AjaxFunction
= "CustomerInquiry";

pagedDataGrid.AddColumn(
"CustomerID", "Customer ID", "20%", "left");
pagedDataGrid.AddColumn(
"CompanyName", "Company Name", "40%", "left");
pagedDataGrid.AddColumn(
"ContactName", "Contact Name", "20%", "left");
pagedDataGrid.AddColumn(
"City", "City", "20%", "left");

foreach (var item in Model.Customers)
{
pagedDataGrid.AddRow();
pagedDataGrid.Po***teRow(
"CustomerID", item.CustomerID , true);
pagedDataGrid.Po***teRow(
"CompanyName", item.CompanyName, false);
pagedDataGrid.Po***teRow(
"ContactName", item.ContactName, false);
pagedDataGrid.Po***teRow(
"City", item.City, false);
pagedDataGrid.InsertRow();
}

}

@Html.RenderNorthwindDataGrid(pagedDataGrid)

  RenderNorthwindDataGrid 函数调用一个MVC HtmlHelper对象,返回一个MvcHtmlString。Data Grid的渲染就变得与其它HTML控件一样。

public static MvcHtmlString RenderNorthwindDataGrid(this HtmlHelper html,
NorthwindWebControls.NorthwindDataGrid dataGrid)
{
string control = dataGrid.CreateControl();
return MvcHtmlString.Create(control);
}

  下面Partial View的名称为MessageBox ,包含Razor View Engine语法的客户端/服务器端代码。这个MessageBox 会贯穿整个示例Web App,为客户端渲染状态与错误信息。

@model NorthwindViewModel.ViewInformation
@{

ViewInformation viewInformation
= new NorthwindViewModel.ViewInformation();

viewInformation.ReturnMessage
= Model.ReturnMessage;
viewInformation.ReturnStatus
= Model.ReturnStatus;

if (viewInformation.ReturnMessage.Count() > 0)
{
<div style="padding: 10px 10px 10px 0px; width:90%">
@
if (viewInformation.ReturnStatus == true)
{
<div style="background-color: Scrollbar;
border: solid 1px black; color: black; padding: 15px 15px 15px 15px">

@foreach (var message in viewInformation.ReturnMessage)
{
<text>@Html.Raw(message)</text>
<br />
}
</div>
}
else
{
// ====== an error has occurred - Display the message box in red ======

<div style="background-color: #f4eded; border:
solid 1px #d19090; color: #762933; padding: 15px 15px 15px 15px">

@foreach (var message in viewInformation.ReturnMessage)
{
<text>@Html.Raw(message)</text>
<br />
}
</div>
}
</div>
}
}

  渲染Customer Inquiry DataGrid

   CustomerInquiry Controller函数调用返回一个JSON对象,客户端JavaScript函数CustomerInquiryComplete函数调用并解析该 JSON对象,得到返回状态值,使用JQuery将返回的Data Grid更新DIV标签

  如果服务器发生错误,页面会渲染前面提到的Partial View —— Message Box。这个过程实际上是一个AJAX调用,利用MVC的灵活控制性,渲染局部页面内容。

function CustomerInquiryComplete(result)
{
if (result.ReturnStatus == true)
{
$(
"#CustomerResults").html(result.CustomerInquiryView);
$(
"#MessageBox").html("");
}
else
{
$(
"#MessageBox").html(result.MessageBoxView);
}

}

  选择一个Customer

   当选择一个下订单的客户(Customer ID域位于Customer Inquiry grid)时,调用JavaScript函数theCustomerSelected,将customer ID传到表单对象,然后使用POST方法提交至服务器。之所以采用POST而非GET方法,是处于安全考虑。

<script language="javascript" type="text/javascript">
function CustomerSelected(customerID) {
$(
"#OrderEntry #CustomerID").val(customerID);
$(
"#OrderEntry").submit();
}
</script>

<form id="OrderEntry" method="post" action="/Orders/OrderEntry">
<input id="CustomerID" name="CustomerID" type="hidden" />
</form>

       Order Entry Header View 

       选定customer后,OrderEntryHeader View被渲染,让用户填入订单的物流信息。OrderEntryHeader View的功能由Knockout控制。

Knowckout – 当MVC遭遇MVVM

  Knockout (或者Knockout.js ,KnockoutJS)是一个开源的JavaScript库,网址为www.knockoutjs.com。Knockout语法简洁、可读性好,能轻 松实现与DOM元素的关联。一旦数据模型的状态发生改变,则立即自动刷新UI。Knockout采用Model-View-View-Model (MVVM)的设计模式来简化动态JavaScript UI。Knockout有效实现了JavaScript与UI HTML呈现的分离。有了Knockout,在写JavaScript时,就不需要在页面中引用UI元素或DOM。

  Knockout设计目标是把任何JavaScript对象当成View Model来使用。只要View Model的属性具有可监听性,就可以使用Knockout将其与UI绑定。一旦属性值发生变化时,UI会被自动刷新。

  Order Entry Header – 编辑模式与显示模式

  Order Header页面的关键功能是,在不重复提交整个页面的前提下,自由切换编辑模式与显示模式。ASP.NET post-back模式通常表现为:用户点击Edit按钮,post提交至服务器,返回后,整个页面被重新刷新。使用Knockout与MVVM数据绑定技术,则可以避免页面重新刷新。这里,我们需要做的仅仅是将Order Header页面去绑定JavaScript创建的View Model。

  数据绑定标签

  为创建一个MVC View来回切换只读与编辑模式,我们为页面的每一个元素都创建单独的DIV与SPAN标签。 一个(编辑模式)包含INPUT HTML控件,另一个(只读)只显示文本。添加Knockout数据绑定标签可以灵活控制HTML元素何时被显示,何时被隐藏。下例中,ShipName 包含一个两个数据绑定标签,前者关联Ship Name的值,后者是一个布尔标签,控制只读或编辑模式。

<div style="float:left; width:150px; height:25px; text-align:right;"
     class
="field-label">Ship To Name:
</div>

<div style="float:left; width:300px; height:25px;">    
    
<span data-bind="visible:EditFields">
        @Html.TextBox(
"ShipName", @Model.Order.ShipName, new Dictionary<string, object> {
        {
"data-bind", "value: ShipName" }, { "style", "width:300px" } })
    
</span>
    
<span data-bind="visible: ReadOnlyMode, text: OriginalShipName"></span>
</div>

  Order Entry显示模式

   当第一次选择一个Order编辑时,此时页面处于只读模式。要创建Knockout与HTML对象的自动绑定,我们必须创建一个JavaScript View Model对象,与Knockout绑定,这样Knockout可以监听View Model对象属性的变化,并自动更新UI。

// Overall viewmodel for this screen, along with initial state

var viewModel
= {

EditFields: ko.observable(
false),
ReadOnlyMode: ko.observable(
false),
DisplayCreateOrderButton: ko.observable(
false),
DisplayEditOrderButton: ko.observable(
false),
DisplayUpdateOrderButton: ko.observable(
false),
DisplayOrderDetailsButton: ko.observable(
false),
DisplayCancelChangesButton: ko.observable(
true),
SelectedShipVia: ko.observable($(
"#OriginalShipVia").val()),
Shippers: ko.observableArray(shippers),
OrderID: ko.observable($(
"#OrderID").val()),
ShipperName: ko.observable($(
"#ShipperName").val()),
CustomerID: ko.observable($(
"#CustomerID").val()),
OriginalShipName: ko.observable($(
"#OriginalShipName").val()),
OriginalShipAddress: ko.observable($(
"#OriginalShipAddress").val()),
OriginalShipCity: ko.observable($(
"#OriginalShipCity").val()),
OriginalShipRegion: ko.observable($(
"#OriginalShipRegion").val()),
OriginalShipPostalCode: ko.observable($(
"#OriginalShipPostalCode").val()),
OriginalShipCountry: ko.observable($(
"#OriginalShipCountry").val()),
OriginalRequiredDate: ko.observable($(
"#OriginalRequiredDate").val()),
OriginalShipVia: ko.observable($(
"#OriginalShipVia").val()),
ShipName: ko.observable($(
"#OriginalShipName").val()),
ShipAddress: ko.observable($(
"#OriginalShipAddress").val()),
ShipCity: ko.observable($(
"#OriginalShipCity").val()),
ShipRegion: ko.observable($(
"#OriginalShipRegion").val()),
ShipPostalCode: ko.observable($(
"#OriginalShipPostalCode").val()),
ShipCountry: ko.observable($(
"#OriginalShipCountry").val()),
RequiredDate: ko.observable($(
"#OriginalRequiredDate").val()),
MessageBox: ko.observable(
"")

}

ko.applyBindings(viewModel);

  我们创建一个Edit Order点击事件函数,当用户点击Edit Order按钮,页面处于编辑模式。代码如下:

$("#btnEditOrder").click(function () {

viewModel.DisplayEditOrderButton(
false);
viewModel.DisplayUpdateOrderButton(
true);
viewModel.DisplayOrderDetailsButton(
false);
viewModel.DisplayCancelChangesButton(
true);
viewModel.EditFields(
true);
viewModel.ReadOnlyMode(
false);

});

   上例中,我们使用Unobtrusive JavaScript这种方式来触发Edit按钮点击事件,实现两种显示与编辑模式的切换。Knockout会监听View Model,实现自动切换。Unobtrusive JavaScript是一项用于页面内容结构与页面呈现分离的新技术。

   用户点击Update Oder 按钮,则调用UpdateOrder 函数。UpdateOrder 函数的功能是抓取View Model的值,并创建一个表示物流信息的JavaScript对象。通过JQuery AJAX调用,该对象将提交给UpdateOrderController函数。

function UpdateOrder() {

var shippingInformation
= new ShippingInformation();

shippingInformation.OrderID
= viewModel.OrderID();
shippingInformation.CustomerID
= viewModel.CustomerID();
shippingInformation.ShipName
= viewModel.ShipName();
shippingInformation.ShipAddress
= viewModel.ShipAddress();
shippingInformation.ShipCity
= viewModel.ShipCity();
shippingInformation.ShipRegion
= viewModel.ShipRegion();
shippingInformation.ShipPostalCode
= viewModel.ShipPostalCode();
shippingInformation.ShipCountry
= viewModel.ShipCountry();
shippingInformation.RequiredDate
= viewModel.RequiredDate();
shippingInformation.Shipper
= viewModel.SelectedShipVia();

var url
= "/Orders/UpdateOrder";

$(
':input').removeClass('validation-error');

$.post(url, shippingInformation,
function (data, textStatus) {
UpdateOrderComplete(data);
});

}

function UpdateOrderComplete(result) {

if (result.ReturnStatus == true) {

viewModel.MessageBox(result.MessageBoxView);
viewModel.OrderID(result.ViewModel.Order.OrderID);
viewModel.ShipperName(result.ViewModel.Order.ShipperName);
viewModel.DisplayEditOrderButton(
true);
viewModel.DisplayUpdateOrderButton(
false);
viewModel.DisplayOrderDetailsButton(
true);
viewModel.DisplayCancelChangesButton(
false);
viewModel.DisplayCreateOrderButton(
false);
viewModel.EditFields(
false);
viewModel.ReadOnlyMode(
true);
viewModel.OriginalShipName(result.ViewModel.Order.ShipName);
viewModel.OriginalShipAddress(result.ViewModel.Order.ShipAddress);
viewModel.OriginalShipCity(result.ViewModel.Order.ShipCity);
viewModel.OriginalShipRegion(result.ViewModel.Order.ShipRegion);
viewModel.OriginalShipPostalCode(result.ViewModel.Order.ShipPostalCode);
viewModel.OriginalShipCountry(result.ViewModel.Order.ShipCountry);
viewModel.OriginalRequiredDate(result.ViewModel.Order.RequiredDateFormatted);
viewModel.OriginalShipVia(viewModel.SelectedShipVia());
}
else
{
viewModel.MessageBox(result.MessageBoxView);
}

for (var val in result.ValidationErrors) {
var element
= "#" + val;
$(element).addClass(
'validation-error');
}

}

      总结
      ASP.NET MVC是一个适用于大型Web应用开发的日益成熟的Web框架。MVC的架构思想是注重分离,对于具有Trial、Error、Discovery的 Web应用开发而言,MVC的学习曲线就显得与众不同。MVC与我们过去一直使用的ASP.NET Web Forms技术与Web Form post-back model技术完全不同。在未来,MVC开发者需要更加注重新兴框架与开源库,增强型MVC的开发。


      本文重点关注的是开源JavaScript库Knockout与JQuery,以及用于交换视图与控制器数据的JSON。建议MVC开发者也多多关注其它 的开发工具与框架,特别是Backbone与JavaScriptMVC。作为比较,后续的文章将会在示例程序Northwind中引入Backbone 与JavaScriptMVC。

开源时代的到来,对与技术人员是一个巨大的考验



QQ:876162454


分享按钮 IP 地址: 已登录   来自: 已登录    返回顶部
 第 1 页 总共 1 页 [共有 1 条记录]
ERP俱乐部 -> Microsoft专栏 -> ASP.NET -> 微软MVC框架功力深厚:Web开发化繁为简
(C)Copyright 2005-2020 www.erpclub.org All Rights Reserved.
Tel:+86-755-26444630
Email:webmaster@yok.com.cn