在 3分钟内,ASP.NET 控件中的控件

分享于 

6分钟阅读

Web开发

  繁體

介绍

无论我们创建什么软件,一个良好的实践都是让它脱离松散耦合的可重用组件。 在 ASP.NET 中,这意味着创建重用控件而不是实现页中的所有功能。 在本文中,我们将基于 DatePicker 插件创建控件,使用我们团队开发的LiveUI框架。 主要是,有两个问题: 第一个是将插头的状态与控制的服务器端属性同步,第二个是通知控件的客户端事件。 我们将看到,使用LiveUI可以解决这两个问题。

背景

LiveUI

由于本文的大多数读者不熟悉 LiveUI,所以很适合简短解释它是什么。 LiveUI是面向富互联网应用程序的网页框架。 它为JavaScript呈现。状态管理和客户端服务器交互提供工具。 我们将使用的最重要的LiveUI类型是 Js。 不久,Js 构建一个JavaScript代码对象模型,由客户端浏览器执行。 例如我们在 C# 中写入: Js.Call("alert", Js.Const("Hello world") ) ,并且浏览器将执行 通知("Hello World"

选择器

DatePickerjQuery.UI的一部分。 它看起来不错,提供了一个非常简单的API。 要创建新的DatePicker,我们应该调用 $(#inputFieldId).datepicker()$(#inputFieldId).datepicker('getdate') 来获取所选日期 $(#inputFieldId).datepicker('setdate') 设置选定日期。 因为它说明了状态同步问题,所以我选择了这个插件。 DatePicker 控件将具有 SelectedDate 属性,该属性应该与插入器的客户端值同步。 控件还将有 ValueChamged 事件,当用户选择日期时应该激发该事件。

控制代码

publicclass Datepicker : ControlBase
{
 publicevent EventHandler ValueSelected;
 public DateTime? Value {
 get { return ClientState.GetValue("value"); }
 set { ClientState.SetValue("value", value); }
 }
 publicoverridevoid OnRender(JsCreationSection section)
 {
 if (!IsRendering)
 return;
 var textInput = Js.Call("$", Js.Const("#" + ClientID));
 textInput.Call("datepicker", Js.Json(
 Js.JsonItem("onSelect", Js.Function(delegate {
 var request = CreateMethodInvocationRequest("OnValueSelected");
 request.Send();
 })
 )));
 ClientState.Synchronize("value", 
 () => textInput.Call("datepicker", Js.Const("getDate")),
 value => textInput.Call("datepicker", 
 Js.Const("setDate"), value));
 }
 publicvoid OnValueSelected()
 {
 if (ValueSelected!= null)
 ValueSelected(this, EventArgs.Empty);
 }
 protectedoverridevoid Render(HtmlTextWriter writer)
 {
 writer.Write("<input type='text' id='{0}'/>", ClientID);
 }
}

Points of Interest

publicoverridevoid OnRender(JsCreationSection section)
{

LiveUI提供了 JavaScript "节",以确保在使用时创建所有的JavaScript对象。 这个原则很简单:我们创建了JavaScript方法 OnRender(JsCreationSection section) 我们可以在 OnRender(JsInitSection section) 中安全地使用它们。 如果你知道的话,应该用 "相位"/"阶段"或者替换单词,除非你建议更好的NAME: )

if (!IsRendering)
 return;

如果页面收到异步AJAX请求,那么除非它被放置在 UpdatePanel 中,否则我们的控件不应该产生任何。 IsRendering 属性封装所有必需的检查。

var textInput = Js.Call("$", Js.Const("#" + ClientID));
textInput.Call("datepicker", Js.Json(
 Js.JsonItem("onSelect", Js.Function(delegate {...

这里代码动态呈现如下所示的JavaScript:

var texbox = $("#myTextbox");
texbox.datepicker({onSelect : function() {....
var request = CreateMethodInvocationRequest("OnValueSelected");
reque request.Send();

LiveUI提供了一个请求管理基础设施,允许客户端对象调用服务器端方法。 换句话说,动态生成的JavaScript代码实例化一个新请求并发送到服务器( 使用默认选项的异步 postback )。 另外,控件的方法应该是json可以序列化的,或者是 JsObject 类型。

ClientState.Synchronize("value", 
 () => textInput.Call("datepicker", Js.Const("getDate")),
 value => textInput.Call("datepicker", Js.Const("setDate"), value));

ClientState 是LiveUI基础设施中的一个重要元素。 我们可以把它当作一个字典来保存客户端对象中的值。 因此,传递给 Synchronize 方法的两个代理只是告诉 ClientState 如何保持 '值'。

结束语

虽然我提供的代码可以在三分钟内实现,但是要理解所发生的事情,需要花。 我们的团队实现了它,并且我们试图使API更清晰并提供更多的样本,但我们的工作没有反馈。 因此,无论你是否喜欢提供的解决方案,请告知我们。


相关文章