当前位置: 首页 > 编程语言 > C#

如何避免在ASP.NET代码隐藏中编写乱七八糟的JavaScript?分享

时间:2023-04-11 11:15:05 C#

如何避免在ASP.NET代码隐藏中编写乱七八糟的JavaScript?我想知道使用Javascript和ASP.NET的最佳实践是什么。我不知道这是否是最佳实践,但我在代码隐藏中添加了javascript客户端事件。它工作正常,但这是最佳实践吗?例如,我有一个单选按钮控件,我在Page_Init中添加了Javascript客户端事件。Pageinit可以被多次调用,因此每次调用Page_It时都会渲染Javascript。此外,很难调试长Javascript字符串。如何更清洁......有办法吗?让我们看一个包含Javascript的变量示例:scripts.Text+="functionValidateDdl"+metachamp.ID+"(sender,args){if("+txtReason.ClientID+".GetText()!=''||"+dynamicControl.ClientID+".style.display=='none'||HiddenFieldSaveError.Contains('"+metachamp.ID+"')){"+dynamicControl.ClientID+".className='';HiddenFieldError.删除("+metachamp.ID+");"+errorImage.ClientID+".SetClientVisible(false);args.IsValid=true;}else{varcomboVal=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函数。在第一阶段之后,我们得到了这样的结果(请原谅部分翻译,它伤害了我的头)。注意闭包构建器模式的使用;在实际代码中,我会更进一步,将其作为一个单独的模块。functionmakeValidator(champId,opts){returnfunction(sender,args){//现在是时候了。////在ASP.NET中使用$get(和$find),尤其是当//处理通过ID查找控件的ASP.NETAJAX集成。////然而,代码使用了一些似乎是DevExpress的//控件,因此必须访问..不同,主要通过//1.`window[clientId]`或//2.`ASPxClientControl.GetControlCollection().GetByName(id);`//这只是需要处理的棘手事情之一;我已经展示了前者的用法//,它可能也需要应用于其他控件。//varreasonControl=window[opts.reasonId];//DX控件vardynamicControl=$get(opts.dynamicControlId);//正常的ASP.NET/DOMvarerrorImage=window[opts.errorImageId];//DX控件if(reasonControl.GetText()!=''||dynamicControl.style.display=="none"){dynamicControl.className='';errorImage.SetClientVisible(false);args.IsValid=真的;}//等}}应该清楚的是,JavaScript代码与任何字符串插值是分开的这是一个正常的函数,当使用特定参数(由API定义)调用时,具有特定的行为。虽然有不同的方法来“加载/注入”此javascript(当UpdatePanels和嵌套/复杂层次结构发挥作用时很重要),但我们假设它当前位于页面标记内。现在,让我们将验证器连接到控件——这完全是虚构的,但它显示了数据绑定的用法,并且实际上在代码隐藏中创建了一个JavaScript“调用”,我们将在第二个原因中看到。(正确使用数据绑定实际上很重要,因为它会延迟调用CreateValidator函数,直到分配控件的ClientID。)"/>然后返回代码隐藏:protectedstringCreateValidator(Controlc){varchampId=c.ClientID;//example,notnecessarytrue//Thensetupothervaluestosupplytothefunction.JSONisnot//*完全*像一个JS对象文字,它足够接近所以我们不关心。//我更喜欢Newtonsoft的Json.NET,但标准支持很好。//(champId也可以在这里序列化,但是我选择显示传递//两个参数,一个未转义;我们假设champId不包含s或's。)varopts=newJavaScriptSerializer().Serialize(new{reasonId=reasonControl.ClientID,dynamicControlId=dynamicControl.ClientID,errorImageId=Error9.ClientId});//括号的使用和返回的实际JavaScript取决于//客户端验证属性是否需要JavaScript来执行(常见)或者//它是否需要稍后执行的函数,如在DevExpress/一些库中找到。//(记住上面的makeValidator返回一个新函数。)//对于DX/DevExpress:returnstring.Format("makeValidator('{0}',{1})",champId,opts);//正常的ASP.NET可能看起来像这样:returnstring.Format("returnmakeValidator('{0}',{1}).apply(this,arguments)",champId,opts);这就是它的要点,包括错误但是,这种方法有很多变体(包括ASP.NETAJAXScriptControl魔术)和需要考虑的微妙之处;要记住和努力的要点是:分离JavaScript代码并使用API传递值。这是任何技术堆栈的经典问题。为了回答这个问题,我记住了几点:不要重复自己(使用WebForms可能会更困难)做一件事,做好我发现客户端功能分为几类:(注:下面的代码可能有一些错误,但它应该给你主要的想法)使用ASP.NETWebForms进行表单验证这对我来说是最痛苦的地方。我目前正在试验FluentValidation和WebForms,实际上进展顺利。我关于验证器的最佳建议:不要使用验证器!这就是为什么人们抱怨WebForms是一个复制粘贴框架。它不必是这样的。在快速代码示例之前不要使用Data[Set|Table|Row]!您获得了所有数据,但没有一种行为。使用像EntityFramework或NHibernate这样的ORM,并让你所有的ASP页面都处理实体类,因为这样你就可以使用像FluentValidation这样的东西:App_Codefile/Models/Entities/Post.csnamespaceProject.Models.Entities{publicclassPost{公共intId{得到;放;}公共字符串标题{得到;放;}publicstringBody{得到;放;}publicDateTimeCreatedAt{get;放;公共日期时间?修改时间{得到;App_Code文件/模型/验证/PostValidator.cs使用FluentValidation;使用Project.Models.Entities;命名空间Project.Models.Validators{publicclassPostValidator:AbstractValidator{publicPostValidator(){RuleFor(p=>p.Title).NotEmpty().Length(1,200);RuleFor(p=>p.Body).NotEmpty();一旦你有了基本的实体和验证器,就可以在后面的代码中使用它们:UserControl/PostControl.ascx.csnamespaceProject.UserControls{publicclassPostControl:System.Web.UI.UserControl{EventArgse){if(Page.IsPostBack){PostValidator验证器=newPostValidator();Postentity=newPost(){//马p实体属性的表单字段Id=Convert.ToInt32(PostId.Value),Title=PostTitle.Text.Trim(),Body=PostBody.Text.Trim()};ValidationResult结果=validator.Validate(entity);if(results.IsValid){//保存到数据库并继续下一页}else{BulletedListsummary=(BulletedList)FindControl("ErrorSummary");//向用户显示错误foreach(varfailureinresults.Errors){LabelerrorMessage=FindControl(failure.PropertyName+"Error")asLabel;如果(errorMessage==null){summary.Items.Add(newListItem(failure.ErrorMessage));}else{errorMessage.Text=failure.ErrorMessage;}}}}else{//显示表单}}...}}UserControls/PostControl.ascx*Title:*Body:ProgrammaticallyAddClientValidation表单字段并使用jQueryValidate触发一些前端验证您可以通过编程方式循环FluentValidation规则:PostValidatorvalidator=newPostValidator();foreach(varruleinvalidator.AsEnumerable()){propertyRule=ruleasFluentValidation.Internal.PropertyRule;如果(propertyRule==null)继续;WebControl控件=(WebControl)FindControl("发布"+propertyRule.PropertyName);foreach(varxinrule.Validators){if(xisFluentValidation.Validators.NotEmptyValidator){control.Attributes["required"]="required";}elseif(xisFluentValidation.Validators.MaximumLengthValidator){vara=(FluentValidation.Validators.MaximumLengthValidator)x;control.Attributes["size"]=a.Max.ToString();control.Attributes["minlength"]=a.Min.ToString();control.Attributes["maxlength"]=a.Max.ToString();}...}}复杂的多字段验证任何需要来自多个字段的数据的验证都不应该在客户端处理。在C#中执行此操作。尝试在ASP页面上将它与HTML和JavaScript拼凑在一起变得很麻烦,并且不足以证明增加的开销和维护问题是合理的。可用性增强这些JavaScript片段可以帮助用户,但对实施业务规则几乎没有作用。在我正在开发的应用程序中,每次用户将焦点从文本框移开时,每个单词都应该大写,所以“foobar”变成了“FooBar”。JavaScript和事件被委托来救援:scripts/foo.js(在每个页面上导入)$(document).on("focusout","input[type=text][data-capitalize-disabled^=true]",函数(事件){event.target.value=event.target.value.replace(/(^|s+)[az]/g,function(match,$1){return$1.toUpperCase();});});要禁用此行为:代码隐藏:PostTitle.Attributes["data-capitalize-disabled"]="true";ASP:如果您可以在ASP文件中管理它,那么现在您已经完全解耦了前端和后端代码!用户交互管理这是前端开发的800磅重的大猩猩。我喜欢在这里使用“小部件模式”,您可以在其中编写一个JavaScript类来包含行为,并使用HTML属性和类名作为JavaScript执行其操作的钩子。scripts/FooWidget.js函数FooWidget(element){this.$element=$(element);this.fillOptions=this.fillOptions.bind(this);this.$element.on("click","[data-action=fillOptions]",this.fillOptions);}FooWidget.prototype={constructor:FooWidget,fillOptions:function(event){//发出ajax请求:varselect=this.$element.find("select:first")[0],option=null;选项=文档。创建元素(“选项”);选项。价值=“……”;选项。文本="...";选择。appendChild(选项);...},focus:function(){this.$element.find(":input:first").focus();}};在您的ASP文件中:FillOptions同样,这里的目标是将JavaScript和HTML捆绑在一起,而不是将任何JavaScript放在C#中。我在javascript中找到了一个很好的客户端事件解决方案。所以,基本上我在.ascx文件中添加了ClientSideEvent。例如,我添加了SelectedIndexChanged事件。当单选按钮的索引发生变化时,它会调用.js文件中的javascript函数。让我们看看:在.ascx中的客户端事件之后,我将javascript添加到名为ClientEvents.js的文件中添加javascript代码函数rblistComment_SelectIndexChanged(s,e){varbtnOk=eval($("[id$=btnOK]").attr(“ID”));vartxtCommentPopup=eval($("[id$=txtCommentPopup]").attr("id"));btnOk.SetEnabled(s.GetValue()!=null);txtCommentPopup.SetVisible(s.GetValue()=='2');最后,在代码隐藏中,我在Page_Load中添加了这段代码。因此它注册脚本并将用户控件与javascript文件链接起来。将javascript文件与用户控件链接以上是C#学习教程:如何避免在ASP.NET代码隐藏中编写乱七八糟的JavaScript?如果分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注---conststringcsname="ClientEvents";conststringcsurl="~/js/EtudeCliniqueScript/ClientEvents.js";输入cstype=this.GetType();ClientScriptManagercs=Page.ClientScript;如果(!cs.IsClientScriptIncludeRegistered(cstype,csname)){cs.RegisterClientScriptInclude(cstype,csname,ResolveClientUrl(csurl));},不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢