js接口 抽象类 在web开发当中的应用

经典js类继承方法

    /*
     * @param subClass Function 子类
     * @param superClass Function 父类
     */
    utility.inherits = function (subClass, superClass) {
        var F = function () {
        };
        F.prototype = superClass.prototype;
        subClass.prototype = new F();
        subClass.prototype.constructor = subClass;
        subClass.superclass = superClass.prototype;
        if (superClass.prototype.constructor == Object.prototype.constructor) {
            superClass.prototype.constructor = superClass;
        }
    }
</pre><pre name="code" class="javascript">来自于JavaScript设计模式的Interface类
    // 接口类
    /*
     * @param name String 接口的名字
     * @param methods Array 接口里面定义的方法
     */
    utility.Interface = function (name, methods) {
        //如果购造函数的参数不等于2个,那么抛出异常
        if (arguments.length != 2) {
            throw new Error("Interface constructor called with " + arguments.length +
                " arguments,but expected exactyl 2.")
        }
        this.name = name;
        this.methods = [];
        //方法数组,保证传进来的methods数组中,每一个元素都是字符串类型
        for (var i = 0, len = methods.length; i < len; i++) {
            if (typeof methods[i] !== "string") {
                throw new Error("Interface constructor expects methods names to bo " +
                    " passed in asastring.");
            }
            this.methods.push(methods[i]);
        }
    }



    //接口实现方法
    utility.Interface.ensureImplements = function (object) {
        //如果参数少于2个,抛出异常,object是待判断实现接口的对象
        if (arguments.length < 2) {
            throw new Error("Function Interface.ensureImplements 被调用,传入 " + arguments.length +
                " 个参数,至少需要2个参数。");
        }
        for (var i = 1, len = arguments.length; i < len; i++) {
            //inter_face为接口,一定要实现Interface类
            //书中使用interface,因是JavaScript中保留字,所以暂替换为inter_face
            var inter_face = arguments[i];
            if (inter_face.constructor !== utility.Interface) {
                throw new Error("Function Interface.ensureImplements:第二个以及之后的参数必须是Interface的实例。");
            }
            for (var j = 0, methodsLen = inter_face.methods.length; j < methodsLen; j++) {
                //对象中是否含有接口中定义的方法
                var method = inter_face.methods[j];
                if (!object[method] || typeof object[method] !== 'function') {
                    throw new Error("Function Interface.ensureImplements: 对象 " +
                        " 没有实现接口 " +
                        inter_face.name +
                        " 的方法 " +
                        method);
                }
            }
        }
    }


    //接口属性检测
    utility.Interface.ensureProperty = function (object, properties) {
        for (var j = 0, len = properties.length; j < len; j++) {
            if (!object[properties[j]]) {
                throw new Error("Function Interface.ensureProperty: 对象中不存在 " +
                    properties[j] +
                    " 属性 ");
            }
        }


    }
父类,定义并实现一个接口
    /**
     *  PageAbstract类构造函数。
     */
    _common.PageAbstract = function () {
        //定义Page的接口和需要实现的方法
        var PageInterface = new utility.Interface('Page', ['initialize', 'render', 'initializeDOM', 'destroyDOM']);
        utility.Interface.ensureImplements(this, PageInterface);
        utility.Interface.ensureProperty(this, ['action', 'handler', 'ajaxCallBack']);


        this.initEvents(this.handler);


        var that = this;
        //窗口unload时候释放资源
        $(window).on('unload', function () {
            that.dispose();
        });
        //如果实现了initializeDOM方法就执行
        if (this.initializeDOM && (typeof this.initializeDOM == 'function')) {
            this.initializeDOM();
        }
        //如果实现了initialize方法就执行
        if (this.initialize && (typeof this.initialize == 'function')) {
            this.initialize();
        }
        //如果实现了render方法就执行
        if (this.render && (typeof this.render == 'function')) {
            this.render();
        }




    }

//类似angularJS的命令式绑定事件方法
    _common.PageAbstract.prototype.initEvents = function (handlers) {
        var that = this;
        var eventsCommon = ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mouseenter", "mouseleave", "keypress", "keydown", "keyup"];
        var eventsBody = ["abort", "beforeunload", "error", "load", "move", "resize", "scroll", "stop", "unload"];
        var eventsForm = ["blur", "change", "focus", "reset", "submit"];
        var eventsMarquee = ["bounce", "finish", "start"];
        var eventsEdit = ["beforecopy", "beforecut", "beforeeditfocus", "beforepaste", "beforeupdate", "contextmenu", "copy", "cut", "drag", "dragdrop", "dragend", "dragenter", "dragleave", "dragover", "dragstart", "drop", "losecapture", "paste", "select", "selectstart"];
        var eventsData = ["afterupdate", "cellchange", "dataavailable", "datasetchanged", "datasetcomplete", "errorupdate", "rowenter", "rowexit", "rowsdelete", "rowsinserted"];
        var eventsOutside = ["afterprint", "beforeprint", "filterchange", "help", "propertychange", "readystatechange"];
        var events = eventsCommon.concat(eventsBody, eventsForm, eventsMarquee, eventsEdit, eventsData, eventsOutside);
        for (var type = 0; type < events.length; type++) {
            if ($('[el-' + events[type] + ']').length > 0) {
                $(document).on(events[type], '[el-' + events[type] + ']', function (evt) {
                    var $target = $(evt.target);
                    var $currentTarget = $(evt.currentTarget);
                    var directiveStr = $currentTarget.attr('el-' + evt.type);
                    var directiveArray= directiveStr.split('&');
                    for(var dirIndex=0;dirIndex<directiveArray.length;dirIndex++)
                    {
                        var directive=directiveArray[dirIndex];
                        if (directive) {
                            var handler = '';
                            var args = [];
                            args.push(evt);
                            if ((directive.indexOf('(') !== -1) && (directive.indexOf(')') !== -1)) {
                                var directiveFun = directive.substring(0, directive.indexOf('('));
                                var directiveArgs = directive.substring(directive.indexOf('('));
                                var directiveNew = 'that._argsFactory' + directiveArgs;
                                handler = directiveFun;
                                var directiveArgs = eval('(' + directiveNew + ')');
                                if(handlers[handler])
                                {
                                    handlers[handler].apply(evt.currentTarget, args.concat(directiveArgs));
                                }
                            }
                            else {
                                handler = directive;
                                if(handlers[handler])
                                {
                                    handlers[handler].apply(evt.currentTarget, args);
                                }
                            }
                        }
                    }
                });
            }
        }
    }


    _common.PageAbstract.prototype._argsFactory = function () {
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
        return args;
    }


    _common.PageAbstract.prototype.dispose = function () {
        //如果实现了destroyDOM方法就执行
        if (this.destroyDOM && (typeof this.destroyDOM == 'function')) {
            this.destroyDOM();
        }
    }

 
//继承父类,父类中实现接口。(具体业务代码,接口的使用)
<script src="../resources/js/public/requirejs/require.js" data-main="../resources/js/controller/page/替换业务脚本"></script>


//使用requireJS定义js依赖
require.config({
    paths: {
        "jquery": "http://e.elong.com/resources/js/public/jquery/jquery-1.9.1",
        "etiming": "../../../../../resources/js/elong/etiming",
        "jqueryui": "http://e.elong.com/resources/js/public/jqueryui/jquery-ui-1.9.2",
        "jquery.validate": "http://e.elong.com/resources/js/public/validate/jquery.validate",
        "datetimepicker": "http://e.elong.com/resources/js/public/datetimepicker/jquery.datetimepicker",
        "qtip2": "http://e.elong.com/resources/js/public/qtip2/qtip2",
        "utility": "http://e.elong.com/resources/js/elong/utility",
        "plugins": "http://e.elong.com/resources/js/elong/plugins",
        "common": "http://e.elong.com/resources/js/elong/common",
        "timingStatistics": "http://e.elong.com/resources/js/elong/timingStatistics",
        "countlySDK": "http://e.elong.com/resources/js/elong/countlySDK",
        "s_code": "http://www.elongstatic.com/common/js/noexpire/s_code.js?t=201401071938"
    },
    shim: {
        "jqueryui": {
            "deps": ["jquery"]
        },
        "jquery.validate": {
            "deps": ["jquery"]
        },
        "datetimepicker": {
            "deps": ["jquery"]
        },
        "qtip2": {
            "deps": ["jquery"]
        },
        "utility": {
            exports: "utility"
        },
        "plugins": {
            "deps": ["jquery"]
        },
        "common": {
            "deps": ["jquery"],
            exports: "common"
        },
        "countlySDK": {
            "deps": ["utility"],
            exports: "countly"
        },
        "timingStatistics":{
            "deps": ["jquery"],
            "exports": "timingStatistics"
        },
        "s_code": {


        }
    }
});


//requireJS异步加载模块
require(["jquery",
    "utility",
    "countlySDK",
    "common",
    "timingStatistics",
    "layout",
    "jqueryui",
    "jquery.validate",
    "qtip2",
    "plugins"], function ($, utility, countly, common,timingStatistics){


    //ElementAdd构造函数。
    var ElementAdd = function () {
        //this指向ElementAdd实例,that方便在this指针改变指向的回调和内部方法中引用当前实例。
        var that = this;
        //ajax的url和href跳转地址依存的属性
        this.action = {
            test: '/bms-web-admin/admin/test?id=1'
        };
        //事件处理函数依存的属性
        this.handler = {
            nimei: function (evt) {
                console.log(this);
                console.log(arguments);
            },
            submitElement: function (evt) {
                countly.recordEvent('createElement');
                var $this = $(this);
                evt.preventDefault();
                if (BMSAdmin.config.frontend.isValidate) {
                    if (that.$form_elementAdd.valid()) {
                        that.$form_elementAdd.submit();
                    }
                }
                else {
                    that.$form_elementAdd[0].submit();
                }
            },
            getTest: function (evt) {
                countly.recordEvent('eventTest1');
                var $this = $(this);
                evt.preventDefault();
                common.ajax({
                    url: that.action.test,
                    data: {'id': 12},
                    success: that.ajaxCallBack.renderCity,
                    error: that.ajaxCallBack.error
                });
            }
        };
        //ajax回调函数依存的属性。
        this.ajaxCallBack = {
            renderCity: function (data) {
               
            },
            error: function (err) {


            }
        };
//调用父类构造函数
        ElementAdd.superclass.constructor.call(this);
    };
    //继承PageAbstract抽象类。必须定义action,handler,ajaxCallBack的公有属性。子类中必须实现initialize,initializeDOM,destroyDOM,render方法。
    utility.inherits(ElementAdd, common.PageAbstract);
    /**
     *  初始化DOM函数,当前DOM中需要使用节点作为属性存储在实例中。
     */
    ElementAdd.prototype.initializeDOM = function () {
        this.$form_elementAdd = $('#form_elementAdd');
    };
    /**
     *  初始化函数。
     */
    ElementAdd.prototype.initialize = function () {
        BMSAdmin.showBackendValidate(this.$form_elementAdd);
        if (BMSAdmin.config.frontend.isValidate) {
            this.$form_elementAdd.validate({
                rules: {
                    name: {
                        required: true
                    },
                    element_key: {
                        isVariables: true,
                        minlength: 2,
                        maxlength: 25,
                        required: true
                    }
                },
                messages: {
                    name: {
                        required: '必填'
                    },
                    element_key: {
                        minlength: '最小长度2',
                        maxlength: '最大长度25',
                        required: 'element_key必填'
                    }
                },
                showErrors: function () {
                    var successList = this.successList;
                    var errorList = this.errorList;
                    for (var i = 0; errorList[i]; i++) {
                        var error = errorList[i];
                        common.showTips("#form_elementAdd", error.element, error.message);
                    }
                    for (var j = 0; successList[j]; j++) {
                        var success = successList[j];
                        common.showTips("#form_elementAdd", success, "");
                    }
                },
                success: $.noop
            });
        }
    };
    /**
     *  渲染页面。
     */
    ElementAdd.prototype.render = function () {


    };
    /**
     *  销毁DOM。
     */
    ElementAdd.prototype.destroyDOM = function () {
        this.$form_elementAdd = null;
    };


    //公有方法
    ElementAdd.prototype.myFunction1 = function () {


    };
    ElementAdd.prototype.myFunction2 = function () {


    };
   



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值