声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版。

UIHelper.Result

在 FineUIMvc 的每一个 HttpPost 的控制器方法里面,你都会看到 UIHelper.Result():

这到底是个什么梗?在 ASP.NET MVC 中并没有 UIHelper 这样一个静态类,为何它能频频出现于每个 HttpPost 的控制器方法中呢?

这一切的一切还要从 ActionResult 入手。

ActionResult

即使第一天接触 ASP.NET MVC 开发人员也应该知道 ActionResult 的含义,作为控制器方法(Action)的返回值(Result),这是一个抽象类。

MVC 内置了很多 ActionResult 的实现类,最常用的可能是下面几个:

1. ViewResult:返回视图。

2. ContentResult:返回一个静态字符串。

3. RedirectResult:重定向到另一个URL,类似于 WebForms 中的 Response.Redirect 函数,返回的HTTP状态码是 302 Redirect。

4. JsonResult:返回一个JSON字符串。

5. HttpNotFoundResult:未找到对象,一般用于URL参数错误,返回的HTTP状态码是 404 Not Found。

还有很多类似的实现,在学习过程中我们会逐步接触。

但是这里面没有 FineUIMvc 回发时能用的 ActionResult,如果你之前对 FineUI(开源版)有所了解的话,就知道 FineUI 回发时返回的是一串 JavaScript 代码:

因此我们就需要自定义 ActionResult 的实现类,来在 FineUIMvc 回发时返回需要的 JavaScript 代码,这个实现类就是 FineUIMvc.AjaxResult。

FineUIMvc.AjaxResult 会处理回发过程中每个控件的改变,并转化为 JavaScript 代码并返回。

比如这样一段 C# 代码:

Alert.Show("你好 FineUIMvc!", MessageBoxIcon.Warning);

在返回的 HTTP 响应中,对应于:

F.alert({message:'你好 FineUIMvc!',messageIcon:'warning'});

这个转化过程就是有 FineUIMvc.AjaxResult 类负责的。

而 UIHelper.Result 就是返回的一个 AjaxResult 实例,内部实现如下:

public static class UIHelper
{ /// <summary>
/// 响应Ajax请求
/// </summary>
/// <returns></returns>
public static AjaxResult Result()
{
return new AjaxResult();
} }

现在回过头来,我们看下 ASP.NET MVC 中的 HttpPost 控制器方法中为啥不需要类似 AjaxResult 的实现:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Gender,Major,EntranceDate")] Student student)
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
return RedirectToAction("Index");
} return View(student);
}

可以看到,原生的 HttpPost 控制器方法直接返回的是视图(ViewResult的实例),也就是整个页面的更新,非AJAX过程。

UIHelper.Button,UIHelper.Grid,UIHelper.Tree...

UIHelper 还有一个重要的用途,那就是根据控件的 ID 获取控件对象,并对其进行更改,UIHelper.Result 会将所有的更改转化为 JavaScript 并返回到客户端。

下面通过一个例子来详细说明这一过程:

在线示例地址:http://fineui.com/demo_mvc#/demo_mvc/Button/Button

在这个例子中,点击第一个按钮,会不断切换第二个按钮[按下的按钮]的状态,第一个按钮的点击事件处理函数:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult btnChangePressed_Click(bool pressed)
{
UIHelper.Button("btnPressed").Pressed(!pressed); return UIHelper.Result();
}

这里面有几个重要的概念:

1. 第二个按钮的当前状态需要通过客户端传入,服务器端对其一无所知(从 WebForms 转入的开发人员常常会忽略这个重要概念)。

2. UIHelper.Button("btnPressed"),用来返回一个 ID 为 btnPressed 的按钮示例。

3. Pressed 方法用来生成一段改变按下状态的脚本。

一个常常令开发人员疑惑的事实是:UIHelper.Button("btnPressed") 返回的并不是你在 View 中定义的名为 btnPressed 的按钮对象!

因为 HTTP 协议本身是无状态,因此服务器端不可能知道客户端的任何数据(除非你显式传入的数据),更无法得知你在 View 中定义的任何内容了。

是不是怀念 WebForms 了,因为在 WebForms 中 ViewState 帮你记下了所有的控件属性,然而你不是很讨厌 ViewState 的臃肿吗?

让我来做个简单的说明,希望能解开你心中的疑惑,在 View 中,我们是这么定义按钮的:

@(F.Button()
.ID("btnPressed")
.Text("按下的按钮")
.EnablePress(true)
.Pressed(true)
)

在回发里面,如果你试图获取按钮的 Text 属性,你会发现这个是空字符串!

UIHelper.Button("btnPressed").Source.Text

因为在 FineUIMvc 内部,只是重新创建了一个 ID=btnPressed 的按钮,默认按钮的 Text 就是空字符串。

为了尽量避免开发人员犯这个错误,所有 UIHelper.Button, UIHelper.Grid... 返回实例中,只能通过方法来操作,比如更改按钮的显示文本:

UIHelper.Button("btnPressed").Text("修改成你想要的文本");

再次强调:UIHelper.Button 返回的是按钮示例只是用来辅助生成前端 JavaScript 的更新脚本,不是 View 中定义的按钮实例。

下面简单看下,在前台如何传入第二个按钮的按下状态:

@(F.Button()
.ID("btnChangePressed")
.Text("改变后面按钮的按下状态")
.CssClass("marginr")
.OnClick(Url.Action("btnChangePressed_Click"), new Parameter("pressed", "F.ui.btnPressed.isPressed()"))
)

通过上一篇文章讲解的自定义参数,我们知道 Paramter 示例中的第二个参数是一段 JavaScript 代码:

F.ui.btnPressed.isPressed()

小结

UIHelper 是一个非常重要的静态类,它有两个主要的用途。

UIHelper.Result 用来返回一个 FineUIMvc.AjaxResult 的实例,用来将回发时的更改转化为 JavaScript 代码返回。

另一个重要用途的返回控件实例(比如 UIHelper.Button,UIHelper.Grid,UIHelper.Tree...),并提供一系列的方法来更新控件,但是要注意这里的控件实例并不是你在 View 中定义的那个实例,只是一个新创建的同名实例而已,方便更新控件属性。

《FineUIMvc随笔》目录:http://www.cnblogs.com/sanshi/p/6473592.html

FineUIMvc随笔(5)UIHelper是个什么梗?的更多相关文章

  1. FineUIMvc随笔 - 动态创建表格列

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户需求 用户希望实现动态创建表格列,在 WebForms 中,我们通过在 Page_Init 中创建列来实现: 但是在 MVC ...

  2. FineUIMvc随笔(1)动态创建表格列

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. <FineUIMvc随笔>目录 FineUIMvc随笔(1)动态创建表格列 FineUIMvc随笔(2)怎样在控件中 ...

  3. FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 通过对比WebForms和MVC中表格数据库分页代码的不同,可以对 MVC 中的数据流转有更加深入的了解. WebForms 中 ...

  4. FineUIMvc随笔(4)自定义回发参数与自定义回发

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 不能忘却的回发 在上一篇文章中,我们对FineUIMvc中的回发进行了详细描述,目的是为了告诉大家: 1. FineUIMvc中 ...

  5. FineUIMvc随笔(7)扩展通知对话框(显示多个不重叠)

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 这篇文章我们将改造 FineUIMvc 默认的通知对话框,使得同时显示多个也不会重叠.并提前出一个公共的JS文件,供大家使用. ...

  6. FineUIMvc随笔 - 不能忘却的回发(__doPostBack)

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户反馈 有网友在官方论坛抛出了这么一个问题,似乎对 FineUIMvc 中的浏览器端与服务器端的交互方式很有异议. 这里面的关 ...

  7. FineUIMvc随笔(3)不能忘却的回发(__doPostBack)

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户反馈 有网友在官方论坛抛出了这么一个问题,似乎对 FineUIMvc 中的浏览器端与服务器端的交互方式很有异议. 这里面的关 ...

  8. FineUIMvc随笔 - 怎样在控件中嵌套 HTML

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户需求 有网友在<FineUI总群1>问这么一个问题:怎么把 HTML 嵌套在控件中? 这是很多刚学习 FineU ...

  9. FineUIMvc随笔(2)怎样在控件中嵌套 HTML

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 用户需求 有网友在<FineUI总群1>问这么一个问题:怎么把 HTML 嵌套在控件中? 这是很多刚学习 FineU ...

随机推荐

  1. 拖动条(SeekBar)的功能和用法

    拖动条和进度条非常相似,只是进度条采用颜色填充来表明进度完成的程序,而拖动条则通过滑块的位置来标识数值——而且拖动条允许用户拖动滑块来改变值,因而拖动条通常用于对系统的某种数值进行调节,比如调节音量等 ...

  2. iOS多线程NSThread和GCD

    在iOS中啊  其实有多种方法实现多线程 这里只记录两个比较常用的  或者说我比较常用的 一个就是BSThread 另一个就是一听名字就比较霸气的妇孺皆知的GCD 先说一下NSThread吧 这个方式 ...

  3. java调用webservice

    http://www.cnblogs.com/sun_moon_earth/archive/2009/02/03/1383308.html http://www.cnblogs.com/siqi/ar ...

  4. (五)Hololens Unity 开发之 手势识别

    学习源于官方文档 Gestures in Unity 笔记一部分是直接翻译官方文档,部分各人理解不一致的和一些比较浅显的保留英文原文 (五)Hololens Unity 开发之 手势识别 HoloLe ...

  5. windows 下odoo 不同版本安装运行问题

    在开发测试不同版本odoo时,总会遇到在同一浏览器下运行出错的状况.虽然可以把不同版本分属不同的端口,但是登录标识会入写用户本地浏览器cookie,由于cookie只匹配域名及路径但是不区分端口, 所 ...

  6. Madifest文件详解

    介绍 Madifest是个XML的描述文件,对于每个DLL有DLL的Manifest文件,对于每个应用程序Application也有自己的Manifest.对于应用程序而言,Manifest可以是一个 ...

  7. 蓝桥网试题 java 基础练习 特殊回文数

    ------------------------------------------------------------------------------------- 简单点,对话的方式简单点 有 ...

  8. 【java设计模式】之 建造者(Builder)模式

    我们还是举上一节的例子:生产汽车.上一节我们通过模板方法模式控制汽车跑起来的动作,那么需求是无止境的,现在如果老板又增加了额外的需求:汽车启动.停止.鸣笛引擎声都由客户自己控制,他想要什么顺序就什么顺 ...

  9. 特殊字符html,css转义大全

    使用方法: 这些字符属于unicode字符集,所以,你的文档需要声明为UTF-8: 下面符号列表的后面有两列编号,它们并不太一样,第一列是用于html的,你需要在前面加上&#符号: 第二列可以 ...

  10. java集合框架02——Collection架构与源码分析

    Collection是一个接口,它主要的两个分支是List和Set.如下图所示: List和Set都是接口,它们继承与Collection.List是有序的队列,可以用重复的元素:而Set是数学概念中 ...