Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS中的单例模式与抽象_Javascript_Design Patterns_Extjs_Oop - Fatal编程技术网

Javascript JS中的单例模式与抽象

Javascript JS中的单例模式与抽象,javascript,design-patterns,extjs,oop,Javascript,Design Patterns,Extjs,Oop,尽管下面的示例利用了ExtJS,但是可以很容易地推断到另一个框架。我是抽象和数据隐藏(以及OO)的爱好者;是否有其他人隐藏数据和成员/函数,或者你认为这种尝试是多余的吗? (注意:我坚信DOM ID几乎不应该硬编码。尽管我使用原型作为典型类的公共方法,但您会注意到下面在原型之外创建的公共函数。) 这张便条很有趣 Ext.ns('Foo.Bar'); /** *Foo.Bar.MainToolbar(单例) */ Foo.Bar.MainToolbar=(函数() { //用于创建和返回对象的临时

尽管下面的示例利用了ExtJS,但是可以很容易地推断到另一个框架。我是抽象和数据隐藏(以及OO)的爱好者;是否有其他人隐藏数据和成员/函数,或者你认为这种尝试是多余的吗? (注意:我坚信DOM ID几乎不应该硬编码。尽管我使用原型作为典型类的公共方法,但您会注意到下面在原型之外创建的公共函数。)

这张便条很有趣

Ext.ns('Foo.Bar');
/**
*Foo.Bar.MainToolbar(单例)
*/
Foo.Bar.MainToolbar=(函数()
{
//用于创建和返回对象的临时私有类-单例
var toolbarClass=Ext.extend(Ext.Container,
{
/**
*建造商(公共)
*/
构造函数:函数(配置)
{
config=config |{};
//私有成员数据========================================
//需要动画锚的ID吗
var accountId=Ext.id(null,“ls accountDiv-”);
var faqId=Ext.id(null,“ls faqDiv-”);
var logoutId=Ext.id(null,“ls logoutDiv-”);
var loginId=Ext.id(null,“ls loginDiv-”);
var rulesId=Ext.id(null,“ls rulesDiv-”);
var itemCls=
'颜色:白色;光标:指针;字体大小:粗体;'+
'字体系列:Helvetica、Arial、Verdana、Lucida Sans Unicode、Sans serif;';
//公共方法*********************************************
/**
*用户登录(公共)-
*/
this.userLogin=函数(用户名、密码)
{
//更新标题栏
Ext.fly(accountId).update(用户名);
Ext.fly(loginId).hide(true);
Ext.fly(logoutId).show(true);
};
//私有方法********************************************
/**
*handleFaqClick(专用)-点击常见问题的处理程序
*/
var handleFaqClick=函数(事件)
{

var dialogMsg='我将发布我的一个大型项目的片段,希望它对您有用。我不是专业人士,因此您可能会发现一些愚蠢或做得不好的事情。我使用的框架是原型

缺少很多代码,但我希望您能够理解其结构

BaseInterface是一个mixin

如果你有问题,请告诉我

function getRandomNumber() {
    return 4; // Chosen by fair dice roll. Guaranteed to be random. Thanks to xkcd.com for this function.
}

/*  -------------------------------
    Core
    -------------------------------
*/

var CORE = function () {
    var mix = function () {
        /* Merge the properties of all the objects given as arguments into the first object, making sure only the first object is modified. Of all the properties with the same name belonging to different objects, the one belonging to the rightmost object wins; that is, precedence goes right to left. */
        var args = $A(arguments);
        if (!args[0]) {
            args[0] = {}; // probably got an empty prototype or something.
        }
        for (var l = args.length, i = 1; i < l; ++i) {
            Object.extend(args[0], args[i]);
        }
        return args[0];
    }

    return {
        mix: mix
    }
}();


var INTERFACE = (function(){

    Notifier = function () {
        CORE.mix(this, {
            max: 5, // max number of notifications shown
            timeout: 8 // a notification disappears after this number of seconds
        }, arguments[0] || {});
        this.elm = ELM.DIV({ // ELM.DIV is too long to explain, it's some trickery I got partly from script.aculo.us - the idea at least.
            attributes:{
                id:'notifier',
                style: 'display: none;'
            }
        })
    };

    CORE.mix(Notifier.prototype, CORE.ELEMENT.BaseInterface, {
        notify: function (msg) {
            if (this.elm) {
                var notes = this.elm.getElementsBySelector('.notification');
                while (notes.length >= this.max) {
                    notes.last().remove();
                }
                this.elm.insert({top: '<div class="notification" style="display: none;">' + msg + '</div>'});
                if (!this.elm.visible()) {
                    this.elm.setStyle('opacity: 0; display: block;');
                    this.elm.morph('opacity: 1;', {
                        duration: 1
                    });
                }
                var newNote = this.elm.down('div');
                newNote.setStyle('opacity: 0; display: block;');
                newNote.morph('opacity: 1;', {duration: 1});
                this.removeNotification.bind(this).delay(this.timeout, newNote);
            }
        },
        removeNotification: function (note) {
            note.remove();
            var notes = this.elm.getElementsBySelector('.notification');
            if (notes.length === 0) {
                this.elm.hide();
            }
        }
    });

    return {
        Notifier: new Notifier() //singleton
    };

})();

/*global Ajax, INTERFACE, CONFIG, CORE, Template $ */

var CONTENT = function () {

    var wallpapers = [];

    wallpapers.toJSON = function () { // needed if I want to send a list of wallpapers back to the server
        var tmp = [];
        this.each(function (wp) {
            if (wp.elm.visible()) {
                tmp.push(wp.toJSON());
            }
        });
        return '[' + tmp.join(', ') + ']';
    };

    var newWallpapers = []; // just a buffer

    Wallpaper = function () {
        CORE.mix(this, {
            thumbUrl: '',
            view: '',
            width: 0,
            height: 0,
            source: ''
        }, arguments[0] || {});
        this.aspect = this.width / this.height;
        switch (this.aspect) {
        case 1.6:
            this.aspect = 2;
            break;
        case 16 / 9:
            this.aspect = 2;
            break;
        case 5 / 4:
            this.aspect = 1;
            break;
        case 4 / 3:
            this.aspect = 1;
            break;
        default:
            if (this.width > 2500) {
                this.aspect = 3;
            } else {
                this.aspect = 0;
            }
        }
        this.dimension = this.width < 1280 ? 0 : (this.width < 1680 ? 1 : (this.width < 1920 ? 2 : 3 ));
        this.hr_aspect = CONFIG.labels.aspect[this.aspect];
        this.hr_source = CONFIG.labels.source[this.source].capitalize();
        this.html = '<div class="source">' + this.hr_source + '</div><a class="thumb" target="_BLANK" href="'+ this.view + '"><img class="thumb" src="' + this.thumbUrl + '" /></a><div class="info"><div class="resolution">' + this.width + 'x' + this.height + '</div><div class="aspect">' + this.hr_aspect + '</div></div>';
    };

    CORE.mix(Wallpaper.prototype, CORE.ELEMENT.BaseInterface, {
        fxParms: null,
        getElement: function () {
            this.elm = document.createElement('div');
            this.elm.className="wallpaper";
            this.elm.innerHTML = this.html;
            return this.elm;
        },
        postInsert: function () {
            if (this.thumbHeight) {
                var x = this.thumbHeight * 200 / this.thumbWidth;
                this.elm.down('img.thumb').setStyle('margin: ' + ((200 - x) / 2) + 'px 0 0;');
            }
            delete this.html;
        },
        toJSON: function () {
            return Object.toJSON({
                thumbUrl: this.thumbUrl,
                view: this.view,
                width: this.width,
                height: this.height,
                source: this.hr_source,
                aspect: this.hr_aspect
            });
        }
    });

    return {
        wallpapers: wallpapers, // wallpapers being shown
        newWallpapers: newWallpapers, // incoming wallpapers
        Wallpaper: Wallpaper // constructor
    };

}();
函数getRandomNumber(){ 返回4;//由公平掷骰选择。保证是随机的。感谢xkcd.com提供此功能。 } /* ------------------------------- 核心 ------------------------------- */ var CORE=函数(){ var mix=函数(){ /*将作为参数提供的所有对象的属性合并到第一个对象中,确保仅修改第一个对象。在属于不同对象的所有同名属性中,属于最右边对象的属性获胜;即优先级从右向左*/ 变量args=$A(参数); 如果(!args[0]){ args[0]={};//可能得到了一个空的原型或其他东西。 } 对于(变量l=args.length,i=1;i=this.max){ notes.last().remove(); } this.elm.insert({top:'+msg+''}); 如果(!this.elm.visible()){ this.elm.setStyle('opacity:0;display:block;'); this.elm.morph('opacity:1;'{ 持续时间:1 }); } var newNote=this.elm.down('div'); setStyle('opacity:0;display:block;'); morph('opacity:1;',{duration:1}); this.removeNotification.bind(this.delay)(this.timeout,newNote); } }, removeNotification:功能(注){ 注意:删除(); var notes=this.elm.getElementsBySelector('.notification'); 如果(notes.length==0){ this.elm.hide(); } } }); 返回{ 通知程序:新通知程序()//单例 }; })(); /*全局Ajax、接口、配置、核心、模板$*/ 变量内容=函数(){ var壁纸=[]; wallpaps.toJSON=function(){//如果要将墙纸列表发送回服务器,则需要此函数 var tmp=[]; 此。每个(功能(wp){ if(wp.elm.visible()){ push(wp.toJSON()); } }); 返回'['+tmp.join(',')+']'; }; var newwallpers=[];//只是一个缓冲区 墙纸=功能(){ 核心。混合(这个{ 拇指URL:“”, 视图:“”, 宽度:0, 高度:0,, 来源:“” },参数[0]|{}); this.aspect=this.width/this.height; 切换(这个方面){ 案例1.6: 这个方面=2; 打破 案例16/9: 这个方面=2; 打破 案例5/4: 这个方面=1; 打破 案例4/3
function getRandomNumber() {
    return 4; // Chosen by fair dice roll. Guaranteed to be random. Thanks to xkcd.com for this function.
}

/*  -------------------------------
    Core
    -------------------------------
*/

var CORE = function () {
    var mix = function () {
        /* Merge the properties of all the objects given as arguments into the first object, making sure only the first object is modified. Of all the properties with the same name belonging to different objects, the one belonging to the rightmost object wins; that is, precedence goes right to left. */
        var args = $A(arguments);
        if (!args[0]) {
            args[0] = {}; // probably got an empty prototype or something.
        }
        for (var l = args.length, i = 1; i < l; ++i) {
            Object.extend(args[0], args[i]);
        }
        return args[0];
    }

    return {
        mix: mix
    }
}();


var INTERFACE = (function(){

    Notifier = function () {
        CORE.mix(this, {
            max: 5, // max number of notifications shown
            timeout: 8 // a notification disappears after this number of seconds
        }, arguments[0] || {});
        this.elm = ELM.DIV({ // ELM.DIV is too long to explain, it's some trickery I got partly from script.aculo.us - the idea at least.
            attributes:{
                id:'notifier',
                style: 'display: none;'
            }
        })
    };

    CORE.mix(Notifier.prototype, CORE.ELEMENT.BaseInterface, {
        notify: function (msg) {
            if (this.elm) {
                var notes = this.elm.getElementsBySelector('.notification');
                while (notes.length >= this.max) {
                    notes.last().remove();
                }
                this.elm.insert({top: '<div class="notification" style="display: none;">' + msg + '</div>'});
                if (!this.elm.visible()) {
                    this.elm.setStyle('opacity: 0; display: block;');
                    this.elm.morph('opacity: 1;', {
                        duration: 1
                    });
                }
                var newNote = this.elm.down('div');
                newNote.setStyle('opacity: 0; display: block;');
                newNote.morph('opacity: 1;', {duration: 1});
                this.removeNotification.bind(this).delay(this.timeout, newNote);
            }
        },
        removeNotification: function (note) {
            note.remove();
            var notes = this.elm.getElementsBySelector('.notification');
            if (notes.length === 0) {
                this.elm.hide();
            }
        }
    });

    return {
        Notifier: new Notifier() //singleton
    };

})();

/*global Ajax, INTERFACE, CONFIG, CORE, Template $ */

var CONTENT = function () {

    var wallpapers = [];

    wallpapers.toJSON = function () { // needed if I want to send a list of wallpapers back to the server
        var tmp = [];
        this.each(function (wp) {
            if (wp.elm.visible()) {
                tmp.push(wp.toJSON());
            }
        });
        return '[' + tmp.join(', ') + ']';
    };

    var newWallpapers = []; // just a buffer

    Wallpaper = function () {
        CORE.mix(this, {
            thumbUrl: '',
            view: '',
            width: 0,
            height: 0,
            source: ''
        }, arguments[0] || {});
        this.aspect = this.width / this.height;
        switch (this.aspect) {
        case 1.6:
            this.aspect = 2;
            break;
        case 16 / 9:
            this.aspect = 2;
            break;
        case 5 / 4:
            this.aspect = 1;
            break;
        case 4 / 3:
            this.aspect = 1;
            break;
        default:
            if (this.width > 2500) {
                this.aspect = 3;
            } else {
                this.aspect = 0;
            }
        }
        this.dimension = this.width < 1280 ? 0 : (this.width < 1680 ? 1 : (this.width < 1920 ? 2 : 3 ));
        this.hr_aspect = CONFIG.labels.aspect[this.aspect];
        this.hr_source = CONFIG.labels.source[this.source].capitalize();
        this.html = '<div class="source">' + this.hr_source + '</div><a class="thumb" target="_BLANK" href="'+ this.view + '"><img class="thumb" src="' + this.thumbUrl + '" /></a><div class="info"><div class="resolution">' + this.width + 'x' + this.height + '</div><div class="aspect">' + this.hr_aspect + '</div></div>';
    };

    CORE.mix(Wallpaper.prototype, CORE.ELEMENT.BaseInterface, {
        fxParms: null,
        getElement: function () {
            this.elm = document.createElement('div');
            this.elm.className="wallpaper";
            this.elm.innerHTML = this.html;
            return this.elm;
        },
        postInsert: function () {
            if (this.thumbHeight) {
                var x = this.thumbHeight * 200 / this.thumbWidth;
                this.elm.down('img.thumb').setStyle('margin: ' + ((200 - x) / 2) + 'px 0 0;');
            }
            delete this.html;
        },
        toJSON: function () {
            return Object.toJSON({
                thumbUrl: this.thumbUrl,
                view: this.view,
                width: this.width,
                height: this.height,
                source: this.hr_source,
                aspect: this.hr_aspect
            });
        }
    });

    return {
        wallpapers: wallpapers, // wallpapers being shown
        newWallpapers: newWallpapers, // incoming wallpapers
        Wallpaper: Wallpaper // constructor
    };

}();
var API = (function() {
    // internal stuff goes in here
    // ...
    // some public methods i'll expose later
    // all have access to the internals since they're inside the closure
    function method1() { ... }
    function method2() { ... }
    var somevar;
    return {
        public_method1: method1,
        public_method2: method2,
        public_var: somevar,
    };
})();

// use the API:
API.public_method1();