• 互联网菜鸟历险记之二


    最近一段时间前端开发的经验

    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>&nbsp;
                        <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;
                });
  • 相关阅读:
    前端的一些小的效果
    数组排序
    查看字符串中出现次数最多的字符以及出现的次数
    让元素垂直水平居中的方式
    MySQL
    数组_集合转换
    Spring_使用(JDBC)
    Spring_Aop基于配置文件
    Spring_Aop_(二)
    Spring_总结
  • 原文地址:https://www.cnblogs.com/walt/p/5080519.html
Copyright © 2020-2023  润新知