互联网菜鸟历险记之二

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

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的话推荐这三种:

[email protected]("title", "action", new { agrs = OO, backurl = Request.Url.OriginalString }, new { @class = "btn btn-default btn-sm" }),这是一个通过直接访问后台controller action的方法,可以

加上参数,以及后退url和控制其样式。

[email protected]("title", "RouteName", new { agrs = XX }, new AjaxOptions { HttpMethod = "Get", OnSuccess = "jsCode" },new { @class = "btn btn-default btn-sm"}),这个是ajax请求,需要在App_Start RouteConfig中配置路由,一般用在不需要跳转页面的请求中,在请求完成时会调用jsCode。

[email protected](“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;
            });
时间: 2025-01-31 15:12:06

互联网菜鸟历险记之二的相关文章

菜鸟译文(二)——使用Java泛型构造模板方法模式

如果你发现你有很多重复的代码,你可能会考虑用模板方法消除容易出错的重复代码.这里有一个例子:下面的两个类,完成了几乎相同的功能: 实例化并初始化一个Reader来读取CSV文件: 读取每一行并解析: 把每一行的字符填充到Product或Customer对象: 将每一个对象添加到Set里: 返回Set. 正如你看到的,只有有注释的地方是不一样的.其他所有步骤都是相同的. ProductCsvReader.java public class ProductCsvReader {       Set<

QA队长历险记(二)

? 滴--滴--滴--一边的锅炉上冷凝水溅到了冰凉的水泥地上.Oliver从一直散发辐射的笔记本电脑屏幕前抬起头,但依稀只看到一片阴影.Seymour Profits,Oliver在G.Wizkins软件公司的新老板,深夜在地下室会议召见了他,他奉命带上他的笔记本电脑和他一直在做的公司最新的移动应用程序的更改."晚上好,Oliver."属于他人的声音让Oliver吓得跳了起来.Profits先生慢悠悠地走出阴影,走到Oliver正坐着的小桌子边."我知道你只来了一个星期,所以

互联网协议入门(二)【转】

原文地址:点击前往 上一篇文章分析了互联网的总体构思,从下至上,每一层协议的设计思想. 这是从设计者的角度看问题,今天我想切换到用户的角度,看看用户是如何从上至下,与这些协议互动的. ============================================================== 互联网协议入门(二) 作者:阮一峰 (接上文) 七.一个小结 先对前面的内容,做一个小结. 我们已经知道,网络通信就是交换数据包.电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从

互联网协议入门(二)转载

上一篇文章分析了互联网的总体构思,从下至上,每一层协议的设计思想. 这是从设计者的角度看问题,今天我想切换到用户的角度,看看用户是如何从上至下,与这些协议互动的. ============================================================== 互联网协议入门(二) 作者:阮一峰 (接上文) 七.一个小结 先对前面的内容,做一个小结. 我们已经知道,网络通信就是交换数据包.电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从而实现两台电脑之间的

互联网协议入门(二)(转)

(接上文) 七.一个小结 先对前面的内容,做一个小结. 我们已经知道,网络通信就是交换数据包.电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从而实现两台电脑之间的通信.数据包的结构,基本上是下面这样: 发送这个包,需要知道两个地址: 对方的 MAC 地址 对方的 IP 地址 有了这两个地址,数据包才能准确送到接收者手中.但是,前面说过,MAC 地址有局限性,如果两台电脑不在同一个子网络,就无法知道对方的 MAC 地址,必须通过网关(gateway)转发. 上图中,1号电脑要向 4 号

Git历险记(二)——Git的安装和配置

各位同学,上回Git历险记(一)讲了一个 “hello Git” 的小故事.有的同学可能是玩过了其它分布式版本控制系统(DVCS),看完之后就触类旁通对Git就了然于胸了:也有的同学可能还如我当初入手Git一样,对它还是摸不着头脑. 从这一篇开始,我就将比较“啰嗦”的和大家一起从零开始经历Git使用的每一步,当然对我而言这也是一个重新认识Git的过程. 使用Git的第一步肯定是安装Git,因为在多数平台上Git是没有预装的.我平时主要的工作环境是windows和Linux(ubuntu),我想看

【网络协议】互联网协议入门(二)

七.一个小结 先对前面的内容,做一个小结. 我们已经知道,网络通信就是交换数据包.电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从而实现两台电脑之间的通信.数据包的结构,基本上是下面这样: 发送这个包,需要知道两个地址: * 对方的MAC地址 * 对方的IP地址 有了这两个地址,数据包才能准确送到接收者手中.但是,前面说过,MAC地址有局限性,如果两台电脑不在同一个子网络,就无法知道对方的MAC地址,必须通过网关(gateway)转发. 上图中,1号电脑要向4号电脑发送一个数据包.它

互联网协议入门(二)

上一篇文章分析了互联网的总体构思,从下至上,每一层协议的设计思想. 这是从设计者的角度看问题,今天我想切换到用户的角度,看看用户是如何从上至下,与这些协议互动的. ============================================================== 转自:http://www.ruanyifeng.com/blog/2012/06/internet_protocol_suite_part_ii.html 作者:阮一峰 (接上文) 七.一个小结 先对前面的内

Ubuntu菜鸟入门(二)—— apt认知,且完善语言安装包

一  语言安装包安装 1  原因 虽然安装的中文版,但是由于安装包很小,所以汉化的不够完全,所以要安装后,再下载语言包进行安装 2  方法 二  apt--软件包管理器 1   软件源 (1) 介绍 apt会自动上网去下载软件,但他可不是四处瞎找,而是去固定的地方找.这个固定的地方有个名字,叫做软件源. 那里专门为每个 Ubuntu 上的apt提供各种打包好的软件以及相关的信息介绍,供apt们下载.这样的软件源有很多,遍布世界各地,超级牛力应该去哪个呢?其实他自己也不知道,他需要一个列表,一个软