jQuery插件模式:更面向对象的东西?

问题描述:

我正在使用jQuery插件,遵循Authoring指南中详细说明的模式。基本上:jQuery插件模式:更面向对象的东西?

(function($) { 
    // Private 
    var doSomething = function($element, settings) { ... } 

    var doSomethingElse = function($element, settings) { ... } 

    // Public 
    var methods = { 
    init: function(options) { ... }, 
    show: function() { ... }, 
    hide: function() { ... }, 
    update: function(content) { ... } 
    }; 

    $.fn.myPlugin = function(method) { 
    if (methods[method]) { 
     return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 
    } else if (typeof method === 'object' || ! method) { 
     return methods.init.apply(this, arguments); 
    } else { 
     $.error('Method ' + method + ' does not exist on jQuery.myPlugin'); 
    } 
    }; 
})(jQuery); 

这是我的不喜欢:我必须将相同的“实例”变量传递给所有的私有函数。我仍然在努力成为一名JS专家 - 所以请原谅我的错误用法 - 但是如果我在Ruby或PHP中做同样的事情,我会创建一个包含所有这些公共和私有成员和方法的类,并且每个该类的实例将对应于$element。然后,我可以做这样的事情(在JS):

var firstElement = new MyPlugin($element, settings); 
firstElement.doSomething(); 

,而不是传递$elementsettingsdoSomething(),它已经访问了那些通过this.$elementthis.settings

让我去这里?我想,我正在寻找更多的面向对象的方法。现在,我完全理解JS没有像Ruby或PHP这样的类。但是在构造函数,模块模式和常规对象表示法(如上面的methods)之间,我不确定哪个是jQuery插件的最佳选项。

有人可以帮助指向正确的方向吗?也许现有的jQuery插件的一些例子可以做到这一点?谢谢!

+0

您的意图是?你每次打电话给你的插件时都试图保持一个独立的状态吗? –

+0

在上面的例子中,你认为'settings'是一个实例变量,还是你指的是其他东西? –

+0

每个元素都有一个单独的状态,是的。 '$ element'和'settings'都是实例变量。 –

jQuery UI Widget Factory可能是一个很好的解决方案。这对于创建任何种类的有状态jQuery插件都很有用,并且可以完全独立于jQuery UI套件的其余部分。

一些有用的链接:


如果你想要一个更裸露的骨头解决方案,我会去用一个普通的构造函数+原型设置可以“正确地”执行任务或使用Revealing Module Pattern来创建函数它将元素和任何选项作为参数并返回公共方法。

使用所述显示模块模式的一个例子:

function myPlugin (element, options) { 
    var privateVar; 

    function privateFunc() {} 

    function publicMethod() {} 

    return { 
     publicMethodName: publicMethod 
    }; 
} 

这种模式比传统的原型设置更整齐了一点,但没有考虑原型链的优点。

编辑:为了澄清,使用这些模式中的任何一种时,应该为每个元素/用途创建一个新实例。

+0

阅读有关Widget Factory的链接,听起来相当不错。我想我会尝试。谢谢! –

+0

+1我同意这种方法可能是OP想要做的,而不是像jQuery插件那样实现功能。 –

将所有有状态的信息存储在插件本身中不一定是个好主意,因为它可以被所有实例共享。一种选择是在插件之外的其他地方存储该数据。

Plugins/Authoring page has a Data section其中描述了如何使用data()函数以插件的形式为每个元素存储供插件使用的信息。

使用数据可以帮助您跟踪来自插件的方法 的变量和状态。命名空间数据合并到一个对象字面 可以很容易地访问您的所有插件的属性从一个 中心位置,以及减少数据命名空间,允许 便于拆卸如果需要的话。

页面上提供的示例使用您的文章中描述的插件模式,但允许“实例”变量与它们关联的元素一起存储。记住

一个关键的事情时,这样做是:

始终命名空间的方法,事件和数据。

编辑:

应该注意的一点,就是在你的例子你的一些功能期待$element作为参数,但是这是没有必要的,因为this将参照正确的事情当通过插件调用这些函数时(因为调用apply()并将上下文设置为正确的this)。

+0

是的,我已经在使用'data()'来存储有状态信息,但我不喜欢我必须在每个函数中检索这些数据才能获得访问权限。 'this'事实上确实指的是DOM元素的公共方法,但我不认为它当一个呼叫的私有方法(除非我用'适用()'来调用这些方法)。 无论如何,你的建议肯定是好东西,但我不认为它可以帮助我找到一个更面向对象的方法。虽然谢谢! –

+0

啊是的!我的错误与您的示例的私有方法有关。我认为将附加功能实现为jQuery插件可能并不是你真正想要的,因为你最终扩展了jQuery。我建议要么使用[控件的方法(http://*.com/questions/6681466/jquery-plugin-patterns-something-more-object-oriented/6682097#6682097),或者没有实现你的功能一个jQuery插件,因为它听起来像那个模型不符合你的要求。 –