How to avoid writing messy JavaScript in an ASP.NET code-behind?(如何避免在 ASP.NET 代码隐藏中编写混乱的 JavaScript?)
问题描述
我在质疑在 ASP.NET 中使用 Javascript 的最佳实践是什么.
I'm questionning about what is the best practice to use Javascript with ASP.NET.
我不知道这是否是最佳实践,但我在代码隐藏中添加了 javascript 客户端事件.它工作正常,但这是最佳做法吗?
I don't know if it's the best practice but I add the javascript client side event inside the codebehind. It is working correctly but is this the best practice?
例如,我有一个单选按钮控件,并在 Page_Init 中添加了 Javascript 客户端事件.页面 init 可以被多次调用,因此每次调用 Page_It 时都会呈现 Javascript.
For example, I got a radio button control and I add the Javascript client side event in the Page_Init. The page init can be recalled multiple time so the Javascript will be rendered each time that the Page_It is called.
此外,很难调试很长的 Javascript 字符串.怎样才能更干净……有什么办法吗?
Also, it is hard to debug a long Javascript string. How it can be more clean ... is there a way?
让我们看一个包含 Javascript 的变量示例:
Let see an example of a variable that contains Javascript :
scripts.Text += "<script type='text/javascript'>function ValidateDdl" + metachamp.ID +
"(sender, args) { if(" + txtReason.ClientID + ".GetText() != '' ||" +
dynamicControl.ClientID +
".style.display == 'none' || HiddenFieldSaveError.Contains('" + metachamp.ID +
"') ){" + dynamicControl.ClientID + ".className='';HiddenFieldError.Remove(" +
metachamp.ID + ");" + errorImage.ClientID +
".SetClientVisible(false);args.IsValid = true;}else{var comboVal = document.getElementById('" +
Image9.ClientID + "'.substring(0,'" + Image9.ClientID +
"'.length - 6) + 'ddl').value ;if (comboVal != '0' ) {args.IsValid = true;HiddenFieldError.Remove(" +
metachamp.ID + ");" + validImage.ClientID +
".SetClientVisible(false);HiddenField.Remove('Bypass-' + '" +
metachamp.ID.ToString() + "');HiddenFieldSaveError.Remove(" + metachamp.ID +
");" + dynamicControl.ClientID + ".className='';" + errorImage.ClientID +
".SetClientVisible(false);}";
推荐答案
第一步是将 JavaScript 从代码隐藏和值的插值中分离出来.与动态构建 JavaScript 不同的是,方法是让 JavaScript 函数给定参数.
The very first step is to separate out the JavaScript from the code-behind and interpolation of values. Instead of dynamically building JavaScript the approach is then to have a JavaScript function that is given arguments.
在第一阶段之后,我们最终得到了以下内容(请原谅部分翻译,这让我很头疼).注意闭包构建器模式的使用;在实际代码中,我会进一步将其作为一个单独的模块.
After the first phase we end up with something like (forgive the partial translation, it was hurting my head) the following. Note the use of a closure-builder pattern; in real code I would further have this as a separate module.
function makeValidator(champId, opts) {
return function (sender, args) {
// Now this is when it gets harry..
//
// Use $get (and $find) inside ASP.NET, especially when
// dealing with ASP.NET AJAX integration to find a control by ID.
//
// HOWEVER, the code uses what appears to be some DevExpress
// controls and thus must be accessed.. differently, mainly either by
// 1. `window[clientId]` or
// 2. `ASPxClientControl.GetControlCollection().GetByName(id);`
// This is just one of those icky things to deal with; I've shown usage
// of the former and it may need to be applied to the other controls as well.
//
var reasonControl = window[opts.reasonId]; // DX control
var dynamicControl = $get(opts.dynamicControlId); // normal ASP.NET/DOM
var errorImage = window[opts.errorImageId]; // DX control
if(reasonControl.GetText() != '' || dynamicControl.style.display == "none") {
dynamicControl.className='';
errorImage.SetClientVisible(false);
args.IsValid = true;
}
// etc.
}
}
应该清楚JavaScript 代码与任何字符串插值是分开的.这是一个正常的函数,当使用某些参数(由 API 定义)调用时,具有特定的行为.虽然有不同的方法来加载/注入"这个 JavaScript(当 UpdatePanels 和嵌套/复杂层次结构发挥作用时这很重要),让我们假设它当前被放置在 中页面的标记.
It should be clear that the JavaScript code is separate from any string interpolation. It is a normal function, that when called with certain arguments (defined by an API), has a certain behavior. While there are different approaches to "load/inject" this JavaScript (which does matter when UpdatePanels and nested/complex hierarchies come into play), let's pretend that it is currently placed inside a <script>
in the markup of the page.
现在,让我们将验证器连接到控件 - 这完全是虚构的,但它显示了数据绑定的用法,并在代码隐藏中实际创建了 JavaScript调用",我们稍后会看到原因.(正确使用数据绑定实际上很重要,因为它延迟调用 CreateValidator 函数,直到分配了控件的 ClientID.)
Now, let's wire up the validator to the control - this is entirely fictitious, but it shows the usage of data-binding and actually creating the JavaScript "invocation" in the code-behind, we'll see why in a second. (Using data-binding correctly is actually important as it delays calling the CreateValidator function until the ClientIDs of the controls have been assigned.)
<!-- Use of the DataBind Container/Eval may be useful, but ignoring that.. --!>
<control:BlahBlah Id="ImaControl"
OnClientValidate="<%# CreateValidator(ImaControl) %>"/>
然后回到代码隐藏:
protected string CreateValidator(Control c) {
var champId = c.ClientID; // example, not necessarily true
// Then setup other values to supply to the function. While JSON is not
// *exactly* like a JS object literal it is close enough so we Just Don't Care.
// I prefer Json.NET from Newtonsoft, but the standard support is just fine.
// (The champId could also be serialized here, but I chose to show passing
// two arguments, one NOT escaped; we assume champId doesn't contain s or 's.)
var opts = new JavaScriptSerializer().Serialize(new {
reasonId = reasonControl.ClientID,
dynamicControlId = dynamicControl.ClientID,
errorImageId = Error9.ClientId
});
// The use of parenthesis and actual JavaScript returned depends on if the
// client-side validation property takes JavaScript to execute (common) or if
// it takes a function to execute later, as found in DevExpress/some libraries.
// (Remember from above that makeValidator returns a new function.)
// For DX/DevExpress:
return string.Format("makeValidator('{0}', {1})", champId, opts);
// Normal ASP.NET might look like this:
return string.Format("return makeValidator('{0}', {1}).apply(this, arguments)",
champId, opts);
}
这就是它的要点,包括错误.但是,这种方法有许多变体(包括 ASP.NET AJAX ScriptControl 魔法)和需要考虑的微妙因素;要记住和争取的重点是:
And that's the gist of it, bugs included. However, there are number of variations of this approach (including the ASP.NET AJAX ScriptControl magic) and subtle factors to consider; the big point to remember and to strive for is:
分离 JavaScript 代码并使用 API 来传达值.
这篇关于如何避免在 ASP.NET 代码隐藏中编写混乱的 JavaScript?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!