标签:
最近一段时间前端开发的经验
1.使用localStorage:(包括选项筛选(不涉及后台请求;绑下拉框数据))
当你的频繁的向后台拿数据进行处理的时候,系统会很卡,如果在第一次加载时获取所有的后台数据,然后放到localStorage中,接下来的处理完全都在前端处理,这样做可以提升系统的性能,我是这样写的:
SetItemData:function(){ //把数据保存到loacalStorage中 var itemData = new Array(); $("#ItemContainer table tbody tr td").find("input").each(function(){ var item = new Object(); item.value = $(this).attr("value"); item.itemname = $(this).attr("itemname"); item.url = $(this).attr("url"); item.id = $(this).attr("itemid"); item.style = $(this).attr("style"); itemData.push(item); }); if (action.check_support()) { localStorage.setItem("ContentItem", JSON.stringify(itemData)); } },
check_support:function ()
{
if(typeof(Storage) == "undefined")
{
alert("Sorry! No web storage support!");
return false;
}
return true;
},
当你在使用数据时可以直接拿出来用,我是拿这些数据做筛选的,如下,我先定义一个Array result,接收筛选之后的数据,并将数据绑定到html中显示。
//Filter and Process SubItem btnfilter:function(){ var filter = $("#txtfilter").val(); if(typeof (filter) == "undefined" || filter == null){return;} //read data from localStroage if (action.check_support()) { var result = new Array(); var storage = window.localStorage; var strJson = storage.getItem("ContentItem"); var Content = JSON.parse(strJson); for(var i in Content){ if(filter != ""){ if(Content[i].itemname.indexOf(filter) > -1){ result.push(Content[i]); } } else{ result.push(Content[i]); } } var str = "<div class=\"row-fluid\" style=\"display:block;\" id=\"menuListEditor\"><div class=\"col-sm-12\"><input id=\"txtfilter\" class=\"input-sm\"> <input id=\"btnfilter\" type=\"button\" value=\"Filter\"></div><div class=\"col-sm-12\"><div class=\"form-group\"><table class=\"table table-striped table-bordered table-hover\" style=\"margin-bottom:0px;\"><thead><tr class=\"info\"><th>选择</th><th>选项名称</th></tr></thead><tbody>"; for(var r in result){ str +="<tr><td><input type=\"checkbox\" name=\"menuId\" value=\""+ result[r].value+"\" url=\""+ result[r].url +"\" itemid=\""+ result[r].id +"\" itemname=\""+ result[r].itemname +"\" style=\""+result[r].style +"\" /></td><td>"+ result[r].itemname +"("+ result[r].value +")</td></tr>"; } str += "</tbody></table></div><div class=\"btn-group col-sm-12 text-center\"><span><button type=\"button\" class=\"btn btn-default\" id=\"btnDetailClose\">关闭</button></span></div></div></div>"; $("#ItemContainer").html(str); $("#txtfilter").val(filter); } action.processItem(MIndex); },
2.可编辑状态下,为一级菜单添加二级选项,显示出归属关系
我在做一些可视化菜单的时候,编辑菜单生成具有层级关系的结构,我们用菜单模板xml,一级菜单已经确定了,我没有用ZTree这样的框架,只是用简单的js满足这样的需求:
进入可编辑页面,一级菜单已经确定,在每个具有子菜单的导航后面有个+ button,点击button 弹出你要选择的菜单选项:其中注意的是,一你要记住你选择的一级导航的index,不然会使二级菜单乱掉,二是
关掉当前的选择框后,再打开一个新的时要是新的(checkbox不能有选中),而打开已经编辑过的时需要显示上次的选中状态。
//process subItem processItem:function(data){ //通过选择器找到点击的一级菜单
var levelOne = $("#sideNav dl[index=‘" + data + "‘]").eq(0);//data就是从外边传入的参数,确定了你点击的是哪一个一级导航
//打开已经编辑过的,要显示上次编辑选中的状态
$(levelOne).find("dd").each(function (index,item) { $("#ItemContainer input[itemid=‘" + $(item).attr("id") + "‘]").attr("checked", "checked"); }); //添加二级菜单 触发checkbox $("#ItemContainer input[name=‘menuId‘]").change(function () { var hasAdded = false;//标记在当前一级导航中,这个选项只能被添加一次 var ItemHref = $(this).attr("url"); var ItemValue = $(this).val(); var ItemName = $(this).attr("itemname"); var ItemStyle = $(this).attr("style"); var ItemId = $(this).attr("itemid"); if ($(this).is(‘:checked‘)) { var that = $(this); $(levelOne).find("dd").each(function (index, item) { if ($(item).attr("id") == ItemId) { alert("已添加此链接,请勿重复添加!"); hasAdded = true; } }); if (!hasAdded) { $("<dd class=\"" + ItemId + "\" name=\"" + ItemName + "\" value=\"" + ItemValue + "\" style=\"" + ItemStyle + "\" id=\"" + ItemId + "\"><a href=\"" + ItemHref + "\"><span>" + ItemName + "</span></a></dd>").appendTo(levelOne).children("dt"); } } else {//将选中的移除 $(levelOne).find("dd[id=‘" + ItemId + "‘]").remove(); } });
3.mvc 中Razor的一些前端方法介绍
Razor我也是刚刚接触,发现有很多意想不到的惊喜,首先是节省了不少的js量,(1)通常,我们在前端写一些button a,都会用js来控制其响应,用Razor的话推荐这三种:
a.@Html.ActionLink("title", "action", new { agrs = OO, backurl = Request.Url.OriginalString }, new { @class = "btn btn-default btn-sm" }),这是一个通过直接访问后台controller action的方法,可以
加上参数,以及后退url和控制其样式。
b.@Ajax.RouteLink("title", "RouteName", new { agrs = XX }, new AjaxOptions { HttpMethod = "Get", OnSuccess = "jsCode" },new { @class = "btn btn-default btn-sm"}),这个是ajax请求,需要在App_Start RouteConfig中配置路由,一般用在不需要跳转页面的请求中,在请求完成时会调用jsCode。
c.@Url.Action(“controller/action”).这个跟a差不多,直接访问后台的controller action
(2)一些标签使用:在项目中,我们有一些输入要做非空验证的,结合使用Razor的表单提交一起使用,同时我们使用ViewModel 进行数据绑定,这样开发非常方便,首先你要引用你的Model(这应该是
MVVM设计模式吧)@model OOXXViewModel,
@Html.TextBoxFor就是我们平时用的text,@Html.TextAreaFor是textarea,另外还有@Html.PasswordFor(m => m.UserPass),@Html.LabelFor(m => m.UserName)
@using (Ajax.BeginForm("action", "Controller", new AjaxOptions() { OnSuccess = "jsCode()" }, new { @class = "form-horizontal", @role = "form" })) { @Html.AntiForgeryToken()//这是防止CSRF攻击的,防止别人伪造页面,黑掉我们网站 <div class="form-group"> <label for="ContentId" class="col-sm-3 control-label">菜单项ID</label> <div class="col-sm-8"> @Html.TextBoxFor(m => m.ContentId, new { @class = "form-control", @readonly = "readonly" }) </div> </div> <div class="form-group"> <label for="ContentName" class="col-sm-3 control-label">菜单名</label> <div class="col-sm-8"> @Html.ValidationMessageFor(m => m.ContentName, null, new { @class = "text-danger" }) @Html.TextBoxFor(m => m.ContentName, new { @class = "form-control", @placeholder = "", @id = "txtName" }) </div> </div> <div class="btn-group col-sm-12 text-center"> <span> <button type="button" class="btn btn-primary" id="btnDetailSubmit">提 交</button> <button type="button" class="btn btn-default" id="btnDetailClose">关闭</button> </span> </div> }
(3)在Razor中调用JS文件可以直接用<script src="@Url.Content("~/Content/jquery.js")"></script>,当然最好的处理静态资源还是用require.js框架,这样可以方便管理加载其他依赖的js;另外对于绑定
页面控件可以使用backbone.js,可以很实时方便的将后台数据绑定到页面控件,
require.config({ baseUrl: document.getElementById("appPath").value + ‘/js/lib‘, paths: { app: document.getElementById("appPath").value + "/js/app", main: document.getElementById("appPath").value + "/js", "jquery": "jquery", "bootstrap": "bootstrap.min", "validate": "jquery.validate.min", "ubo-ajax": "jquery.unobtrusive-ajax.min", "validate-ubo": "jquery.validate.unobtrusive.min" }, shim: { "ubo-ajax": ["jquery"], "validate": ["jquery"], "bootstrap": ["jquery"], "validate-ubo": ["jquery", "validate"] } }) require(["app/action", "underscore", "backbone", "jquery", "jquery-ui", "bootstrap", "validate", "validate-ubo"], function (action, underscore, Backbone) { var AppView = Backbone.View.extend({//将时间数据,以及页面所触发的事件绑定到控件中 el: $(‘body‘), initialize: function () { $("#OnlineDay").datepicker({ dateFormat: ‘yy-mm-dd‘, showTime: true, constrainInput: false }); $("#OfflineDay").datepicker({ dateFormat: ‘yy-mm-dd‘, showTime: true, constrainInput: false }); }, events: { ‘click #btnSearch‘: action.btnSearch, ‘click #btnSaved‘: action.btnSaved, ‘click #ddltemplateId‘: action.ddltemplateId, ‘click #btnReturnList‘: action.btnReturnList, ‘click #EditTemplateId‘: action.EditTemplateId, ‘click #btnfilter‘: action.btnfilter } }); var app = new AppView(); return app; })
(4)Razor的Ajax.BeginForm()使用,UpdateTargetId是对DOM id为txtResult的模块进行更新处理
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId="txtResult" }))
{
<input type="submit" value="Button"/>
<span id="txtResult"/>
}
4.Jquery .$Post()请求
当你的系统js访问的域名发生变化时,即从a.com访问了b.com的资源时,这就是跨域的请求处理:
$.ajax({
url: "http://.......",
type: ‘GET‘,
dataType: ‘JSONP‘,//here,这是跨域的ajax请求处理
success: function (data) {
}
});
5.关于js中的this问题
this在js中我们通常用来作为一个对象使用,如
$("#ItemContainer input[name=‘menuId‘]").change(function () {
var hasAdded = false;
var ItemHref = $(this).attr("url");我们一般认为this就是当前change的对象,但是对于ie浏览器中尤其是ie10之下的版本,this是指向的window的,这就让人很纠结,但是解决的方法还是有的,
可以用参数来重新定位this:下面代码是一个for循环中,对一个array进行遍历当某一个被click时触发addFloatEventHandler()方法
addFloatEventHandler(langlis[i], ‘click‘, function (e) { var _this = e.srcElement || e.target;//_this重新指向事件 var langid = _this.id; });
标签:
原文地址:http://www.cnblogs.com/walt/p/5080519.html