javascript-如何在交互式Web应用程序中实现OOP模式(在jQuery的帮助下)?

有时,使用jQuery会诱使您滥用其功能(至少对我来说是因为其选择器匹配功能).这里和那里的事件处理程序.实用程序功能在这里和任何地方都可以.代码一致性似乎几乎不存在.我想通过实现OOP模式来减轻该问题,但是由于我具有C和python背景,因此在javascript中实现它会使我有点头疼.

下面的代码使用OOP模式,但是我不确定我的实现是否是好的做法.我怀疑自己的实现的原因是因为my last * question中的第三条注释.我知道这只是他所评论的代码中的一个特定细节,但这也使我想知道我正在代码中实现的其他模式.

如果您能指出我的模式中的缺陷和陷阱和/或您有任何建议,我将不胜感激.提前谢谢了.

(这段代码是我正在开发的东西的简化,但是想法很相似)

Live Example

$(function(){
    var stream = new Stream();
});


/*          Stream Class
------------------------------------------*/
function Stream(){

    // Disables multiple Stream objects
    if (this.singleton)
        return
    else
        this.__proto__.singleton = true;


    this.elements = jQueryMapping(this.selectors) // Converts a map of selectors to a map of jQuery objects
    this.initEvents();
}

Stream.prototype.singleton = false;

Stream.prototype.selectors = {
    stream : '#stream',
    post_content : '#post-content',
    add_post: '#add-post',
    // ... more action selectors
}

Stream.prototype.initEvents = function(){
    this.elements.add_post.click(this, this.addPost);
    // ... more action event-listeners
}

Stream.prototype.addPost = function(e){
    var self = e.data;
    var post_content = self.elements.post_content.val();

    if (post_content)
        self.elements.stream.append(new Post(post_content));
}


/*          Post Class
------------------------------------------*/
function Post(post_content){
    this.$element = $('<li>')
                        .text(post_content)
                        .append('<button class="delete-post">Delete</button>');

    this.elements = jQueryMapping(this.selectors, this.$element);
    this.initEvents();

    return this.$element;
}

Post.prototype.selectors = {
    delete_post: 'button.delete-post',
    // ... more action selectors
}

Post.prototype.initEvents = function(){
    this.elements.delete_post.click(this.deletePost);
    // ... more action event-listeners
}

Post.prototype.deletePost = function(){
    $(this).parent().slideUp();
}


/*          Utils
------------------------------------------*/
function jQueryMapping(map, context){
    // Converts a map of selectors to a map of jQuery objects

    var $map = {};
    $.each(map, function(key, value){ 
            $map[key] = (context) ? $(value, context) : $(value);
    });

    return $map;
}

解决方法:

我相信您的代码设计过度.我已经进行了分解,并简化了它,如here所示.如果您真的想进行繁琐的OOP设置,建议您使用客户端MVC(主干,剔除等)结构来正确执行此操作或使其保持轻量化.

我将对您的代码进行一般性反馈.

/*          Stream Class
------------------------------------------*/
function Stream(){

    // Disables multiple Stream objects
    if (this.singleton)
        return
    else
        this.__proto__.singleton = true;


    this.elements = jQueryMapping(this.selectors) // Converts a map of selectors to a map of jQuery objects
    this.initEvents();
}

没有理由使用这样的单例.使用.__ proto__也很不好

我会推荐这样的模式.

var Stream = (function() {
    var Stream = function() { ... };

    // prototype stuff

    var stream = new Stream();

    return function() {
         return stream;
    };
})());

不需要在原型上存储像这样的哈希数据.

Stream.prototype.selectors = {
    stream : '#stream',
    post_content : '#post-content',
    add_post: '#add-post',
    // ... more action selectors
}

您可以将其作为默认哈希值包含在内.

(function() {
    var defaults = {
        stream : '#stream',
        post_content : '#post-content',
        add_post: '#add-post',
        // ... more action selectors
    }

    function Stream() {
         ...

         this.elements = jQueryMapping(defaults);
    }

}());

您的效用函数可能会略有优化.

$map[key] = (context) ? $(value, context) : $(value);

这可以重写为

$map[key] = $(value, context)

由于如果上下文是未定义的,则只需传入未定义的参数,这与不传入参数相同.

上一篇:php-在网站上创建交互式地块R-图


下一篇:MySQL 的连接时长控制--interactive_timeout和wait_timeout