`
jinweijie
  • 浏览: 7563 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Creating JavaScript objects from ASP.NET objects

阅读更多
from http://www.netfxharmonics.com/2007/09/Creating-JavaScript-objects-from-ASPNET-objects.aspx

If you have worked with ASP.NET for any length of time you probably know that the ASP.NET ID you set on a control on the server-side changes when it gets to the client side.  For example, if you have a textbox with an ID of "txtUsername" in ASP.NET, you will probably have a textbox with an ID of something like "ctl100_txtUsername".  When working only with server-side code, this is fine.  However, I'm a JavaScript programmer as well as a .NET programmer.  Most of my applications are heavily Ajax based and sometimes the entire application through all of its screens and uses will have ZERO postbacks.  So, it's important for me to have the correct ID on the client.  So, I need to be able to access controls on the client-side.  Not only so I can access the ID from a JavaScript functions, but also so I can set loosely-coupled events on objects.

Typically the way people get around this is with simple, yet architecturally blasphemous techniques.  The first technique is to break a foundational rule of software architectural (e.g. low-coupling) by putting an event right on the element itself.  That is, they hard code the event they want to raise right on the control itself.  This is a very strange technique as the .NET developers who do this technique are usually thos wwho would never put a server-side event on a control using OnServerClick.  Somehow, they think that putting an even directly on a client-side control by OnClick is less wrong.  This is obviously a case of extremely object coupling, an extremely poor architectural practice.  In case you can't picture it, here's what I'm talking about:

<asp:TextBox id="txtUsername" runat="server" Text="Username" OnClick="ClearBox( );"></asp:TextBox>

A much, much better way of getting around this is to use the ClientID property of an ASP.NET control to assign a multi-cast JavaScript event to that button.  However, we must be careful with this technique as it too could lead to design problems.  The most obvious problem is that of spaghetti code, the mixing of two or more languages in one same file.  Professional ASP.NET developers know that to have a sound system, you must be using code-behinds.  The ASP.NET development model greatly improves the readability of code by making sure that the C# (or VB) code and the ASP.NET declarations are completely separate.  While reading one page, your brain doesn't need to be flipping all over the place trying to translate multiple languages at the same time.  To be sure, those of us from the PHP world know that with time you can become very proficient in developing in spaghetti code, but, on the other hand, those of us who have taken over a project from another person know the pains of trying to decode that slop.

The typical technique for applying loosely-coupled events (and for many other JavaScript functionality) is actually very strange.  Though the ASP.NET developers will insist on a separation for their C# (or VB) away from their ASP.NET pages, they have no problem throwing JavaScript in the midst of C# code.  This is almost as bad as putting ad-hoc SQL queries in your C# code (very bad) or coupling CSS rules to an element via the HTML "style" attribute, thereby making the solution absolutely impossible to theme and breaking any chance of debugging CSS problems (very, very bad).  JavaScript and CSS have had a code-behind model long before ASP.NET was around.  So, we need to respect the practices of code separation as much as possible.  To this end, we need a better solution than throwing a large block of JavaScript in to an ASP.NET page.

Here is an example of the old technique using legacy JavaScript (in contrast to Modern JavaScript shown in a bit):

<script type="text/javascript">
function ClearBox( ) {
document.getElementById(<%=txtUsername.ClientID%>).value = '';
}

document.getElementById(<%=txtUsername.ClientID%>).onclick = ClearBox;
</script>

<
asp:TextBox id="txtUserName" runat="server" Text="Username"></asp:TextBox>

 

Typically, however, you will see a TON of JavaScript code simply thrown into the page with no respect for code separation and with no possibility for multicast events.  (Furthermore, not only is this code raw spaghetti code, that function isn't even in a JavaScript namespace.  Please see my link below for more information on JavaScript Namespaces;  If you are familiar with .NET namespaces, then you have a head start on learning JavaScript namespaces.  Would you ever throw a class into an assembly that without putting it in a namespace?  Probably not... it's the same idea in JavaScript.)

Fortunately, there is a better model using a couple of JavaScript files.  The first JavaScript file (Event.js) is one of my standard files you will see in all of my JavaScript applications:

var Event = {
Add: function (obj, evt, func, capture) {
if(obj.addEventListener) {
obj.addEventListener (evt, func, capture);
}
else if(obj.attachEvent) {
obj.attachEvent('on' + evt, func);
}
},
Remove: function (obj, evt, func, capture) {
if(obj.removeEventListener) {
obj.removeEventListener (evt, func, capture);
}
else if(obj.detachEvent) {
obj.detachEvent('on' + evt, func);
}
}
}

This Modern JavaScript document, simply allows you to add or remove events from an object.  It's fairly simple.  Here's a file (AspNet.js) you will find in some of my applications:

var AspNet = {
Objects: new Object( ),

RegisterObject: function(clientId, aspNetId, encapsulated) {
if(encapsulated) {
eval('AspNet.Objects.' + clientId + ' = D(aspNetId)');
}
else {
eval('window.' + clientId + ' = D(aspNetId)');
}
}
};

This one here is where the meat is.  When you call the RegisterObject function you will actually register an ASP.NET control with JavaScript so that you can use it without needing the fancy ASP.NET ClientID.  Furthermore, it also allows you to use the object directly in JavaScript without relying on document.getElementById( ).  This technique is actually a cleaner version of the one I previously mentioned.  It does require you to put a little JavaScript in your page, but that's OK as it's ASP.NET specific code used to register itself with JavaScript; you aren't really breaking any rules here.  To use the above JavaScript namespace , you simply put code similar to the following somewhere in your ASP.NET page:

<script type="text/javascript">
Event.Add(window, 'load', function(evt) {
// ASP.NET JavaScript Object Registration
AspNet.RegisterObject('txtUsername', '<%=txtUsername.ClientID%>');
AspNet.RegisterObject('txtPassword', '<%=txtPassword.ClientID%>');


Initialization.Init( );
}, false);
</script>

Basically, when the page loads your objects will be registered.  What does this mean?  It means you can use the object as they are used in this Initialization.js file (another file in all of my JavaScript projects):

var Initialization = {
Init: function( ) {
txtUsername.onclick = function(evt) {
if(!txtUsername.alreadyClicked) {
txtUsername.value = '';
txtUsername.alreadyClicked = true;
}
};

txtPassword.onclick = function(evt) {
if(!txtPassword.alreadyClicked) {
txtPassword.value = '';
txtPassword.alreadyClicked = true;
txtPassword.type = 'password';
}
};
}
};

As you can see there is no document.getElementById( ) here.  You are simply naturally using the object as if it were strongly typed.  The best part is that to support another ASP.NET page, you simply have to put a similiar JavaScript script block in that page.  That's it.  Furthermore, if you don't want to access the control directly, perhaps because you are worried about potential naming conflicts you can send a boolean value of true as the third argument in the AspNet.RegisterObject function, this will put the objects under the AspNet.Objects namespace.  Thereby, for example, making txtUsername accessible by "AspNet.Objects.txtUsername" instead of simply "txtUsername".

There is one catch though: you have to assign events to your window.load event using multi-cast events.  In other words, if at any point you assign an event directly to the window.load event, then you will obviously overwrite all events.  For example, the following would destroy this entire technique:

window.load = function(evt) {
// Do something...
}

This should not be a shocker to C# developers.  In C#, when we assign an event we are very careful to make sure to assign it using the "+=" syntax and not the "=" syntax.  This the same idea.  It's a very, very poor practice to ever assign events directly to the window.load event because you have absolutely no idea when you will need more than one event to call more than one function.  If your MasterPage needs the window.load event, your Page needs the window.load event, and a Control needs the window.load event, what are you going to do?  If you decide you will never need to do multicast events on load and then get a 3rd party tool that relies on it, what will you do when it overrides your load event or when you override its?  Have fun debugging that one.  Therefore, you should always use loosely-coupled JavaScript multi-cast events for window.load.  Furthermore, it's very important to following proper development practices at all times and never let deadlines stop your from professional quality development.

分享到:
评论

相关推荐

    Maximizing ASP.NET

    Creating Web services from existing code and using remote services just like local objects Using ASP.NET 2.0's rich security and membership classes Personalizing siteswithout unnecessary complexity ...

    Pro ASP.NET MVC 5 Platform(Apress,Adam.Freeman,2014)

    The power of ASP.NET MVC 5 stems from the underlying ASP.NET platform. To make your ASP.NET MVC applications the best they can be, you need to fully understand the platform features and know how they ...

    [ASP.NET] ASP.NET 4 高级程序设计 (C# 2010 实现) (英文版)

    ASP.NET 4 is the principal standard for creating dynamic web pages on the Windows platform. Pro ASP.NET 4 in C# 2010 raises the bar for high-quality, practical advice on learning and deploying ...

    ASP.NET - Module 7_Creating a Microsoft ASP.NET Web Application

    ### ASP.NET - Module 7_Creating a Microsoft ASP.NET Web Application #### 概览 本模块主要介绍了如何创建一个Microsoft ASP.NET Web应用程序,并深入探讨了Web应用程序的要求、ASP.NET的新特性、页面间信息共享...

    Bootstrap for ASP.NET MVC

    This book guides you through the process of creating an ASP.NET MVC website from scratch using Bootstrap. You will learn about various Bootstrap components as well as techniques to include them in ...

    ASP.NET 3.5 高级程序设计英文第3版:Pro ASP.NET 3.5 in C# 2008: Includes Silverlight 2(part1)

    They cover ASP.NET 3.5 as a whole, illustrating both the brand–new features and the functionality carried over from previous versions of ASP. This book will give you the knowledge you need to code ...

    ASP.NET 2.0 Beta Preview

    ASP.NET 2 Beta Preview is timed to coincide with the first widespread beta release of ASP.NET "Whidbey" — the new version of Microsoft’s popular technology for creating dynamic Web sites that pull ...

    asp.net mvc 增删改查通过ado.net实现

    ASP.NET MVC是一个强大的框架,用于构建可伸缩、高性能的Web应用程序。在.NET平台上,它提供了灵活的架构,使得开发者可以使用模型-视图-控制器(MVC)设计模式进行开发。ADO.NET则是.NET Framework中用于数据库交互...

    Test-Drive ASP.NET MVC

    You’ll learn how to do everything from creating your first test, to building REST web services, to deploying your finished ASP.NET MVC applications. Test-Drive ASP.NET MVC gets you started with all ...

    Programming ASP.NET

    New material covers creating ASP.NET pages for mobile devices. Since most web applications and web services involve retrieving data and returning it to a client browser, Programming ASP.NET Second ...

    asp.net core英文版教程

    ### ASP.NET Core 英文版教程知识点概览 #### Introduction - **ASP.NET Core**:一个用于构建现代 Web 应用程序的免费、开源框架,支持跨平台运行。 - **特性**:轻量级、模块化,易于部署,支持云环境。 #### ...

    ASP.NET AJAX Control Toolkit

    * AjaxControlToolkit - A set of sample ASP.NET AJAX controls and source * SampleWebsite - A web site that demonstrates how to use the controls and contains the rest of the Toolkit documentation * ...

    Essential Docker for ASP.NET Core MVC

    from creating a consistent development environment for your team to deploying a project and scaling it up in production. By the end of the book, you will have a solid understanding of what Docker ...

    Bootstrap for ASP.NET MVC, 2nd Edition

    This book guides you through the process of creating an ASP.NET MVC website from scratch using Bootstrap. You will learn about the various Bootstrap components as well as techniques to include them in...

Global site tag (gtag.js) - Google Analytics