如何避免在ASP.NET code-背后写凌乱的JavaScript? [英] How to avoid writing messy JavaScript in an ASP.NET code-behind?

查看:276
本文介绍了如何避免在ASP.NET code-背后写凌乱的JavaScript?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我questionning什么是使用JavaScript与ASP.NET中的最佳实践。

我不知道这是否是最好的做法,但我添加了codebehind内的JavaScript客户端事件。它工作正常,但是这是最好的做法是什么?

例如,我有一个单选按钮,控制和我在Page_Init添加JavaScript客户端事件。页面初始化可以调用多个时间这样的Javascript将各自的Page_It被调用的时候呈现。

另外,也难以调试长的Javascript串。怎样才可以更干净......有没有办法?

让看到包含的JavaScript变量的例子:

  scripts.Text + =<脚本类型=文/ JavaScript的'>功能ValidateDdl+ metachamp.ID +
(发件人,参数){如果(+ txtReason.ClientID +.GetText()!=''||+
dynamicControl.ClientID +
.style.display =='无'|| HiddenFieldSaveError.Contains('+ metachamp.ID +
')){+ dynamicControl.ClientID +.className =''; HiddenFieldError.Remove(+
metachamp.ID +); + errorImage.ClientID +
.SetClientVisible(假); args.IsValid = TRUE;}其他{VAR comboVal =的document.getElementById('+
Image9.ClientID +'.substring(0,'+ Image9.ClientID +
'。长度 - 6)+'DDL')值!如果(comboVal ='0'){args.IsValid = TRUE; HiddenFieldError.Remove(+
metachamp.ID +); + validImage.ClientID +
.SetClientVisible(假); HiddenField.Remove('Bypass-++
metachamp.ID.ToString()+'); HiddenFieldSaveError.Remove(+ metachamp.ID +
); + dynamicControl.ClientID +.className =''; + errorImage.ClientID +
.SetClientVisible(假);};


解决方案

非常的第一个的第一步是从code-后面值插值分离出的JavaScript。而不是动态生成的JavaScript的方法是然后有一个的定参数的JavaScript函数

我们最终的东西像第一阶段结束后(原谅的部分翻译,有人伤害我的头)以下。注意使用封闭建设者格局;在现实code我会进一步有这个作为一个单独的模块。

函数makeValidator(champId,选择采用){
    返回功能(发件人,参数){
        //现在,这是当它得到哈利..
        //
        //使用$ GET($和发现)内ASP.NET,特别是当
        //处理ASP.NET AJAX集成,找到ID的控制。
        //
        //但是,code使用这似乎是一些DevEx preSS
        //控制,因此必须进行访问..不同,主要是或者通过
        // 1.`窗口[的clientId]`或
        // 2`ASPxClientControl.GetControlCollection()GetByName方法(ID);`
        //这只是那些恶心的事情要处理之一;我已经展示了使用
        //前和其可能需要被施加到其他的控制为好。
        //
        VAR reasonControl =窗口[opts.reasonId] // DX控制
        VAR dynamicControl = $ GET(opts.dynamicControlId); //正常ASP.NET/DOM
        VAR errorImage =窗口[opts.errorImageId] // DX控制
        如果(reasonControl.GetText()!=''|| dynamicControl.style.display ==无){
            dynamicControl.className ='';
            errorImage.SetClientVisible(假);
            args.IsValid = TRUE;
        }
        //等等。
    }
}

这应该清楚的 JavaScript的code是任何字符串插值单独的。这是一个正常的功能,当与某些参数(由API定义)调用,具有一定的行为。虽然有装入/注入不同的方法这段JavaScript(这事的确时的UpdatePanel和嵌套/复杂的层次发挥作用),让我们pretend其目前放在&LT内部;脚本&GT ; 在页面的标记

现在,让我们连线了验证器来控制 - 这完全是虚构的,但它显示的数据绑定,实际上开创了code-背后的JavaScript调用,我们就会明白为什么使用在第二个。 (使用数据绑定是正确的,因为它的延迟的调用CreateValidator函数,直到控件的ClientID已分配。其实重要)

<! - 在集装箱的DataBind /评估和演示的使用可能是有用的,但忽略了。 - &GT ;
<控制:BlahBlah n =ImaControl
                  OnClientValidate =<%#CreateValidator(ImaControl)%GT;/>

和再回到code-背后:

保护字符串CreateValidator(控制C){
    VAR champId = c.ClientID; //例如,不一定是真实的    //然后设置其他值提供给函数。虽然JSON是不
    // * *完全相同像JS对象字面就足够接近,所以我们也就无所谓了。
    //我preFER Json.NET从Newtonsoft,但标准的支持就好了。
    //(该champId也可以在这里连载的,但我还是选择了传球展示
    //两个参数,一是没有逃脱;我们假设champId不包含\\ s或的。)
    VAR OPTS =新的JavaScriptSerializer()。序列化(新{
        reasonId = reasonControl.ClientID,
        dynamicControlId = dynamicControl.ClientID,
        errorImageId = Error9.ClientId
    });    //使用括号与实际的JavaScript退换,如果依赖于
    //客户端验证属性采用JavaScript的执行(普通),或者如果
    //它需要一个功能之后执行,如DevEx preSS /一些库中找到。
    //(从makeValidator上述记住返回一个新的功能。)    //对于DX / DevEx preSS:
    返回的String.Format(makeValidator('{0}',{1}),champId,选择采用);    //普通ASP.NET可能是这样的:
    返回的String.Format(回归makeValidator('{0}',{1})。申请(这一点,参数),
                    champId,选择采用);
}

这就是它的主要内容,包括错误。不过,也有这种做法(包括ASP.NET AJAX ScriptControl的魔法)和微妙的因素来考虑的变化数;大一点要记住,争取为:

分隔的JavaScript code和使用API​​来沟通值

I'm questionning about what is the best practice to use Javascript with ASP.NET.

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?

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.

Also, it is hard to debug a long Javascript string. How it can be more clean ... is there a way?

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);}";

解决方案

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.
    }
}

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.

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) %>"/>

And then back to the code-behind:

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);
}

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:

Separate the JavaScript code and use an API to communicate values.

这篇关于如何避免在ASP.NET code-背后写凌乱的JavaScript?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆