2009-12-01 81 views
3

我创建了一个jQuery插件,允许用户与树交互(创建,更新,删除节点)。至少有十几种与树交互的方法。理想情况下,我不想像现在这样使用所有这些特定于树的方法来污染jQuery命名空间,因为每种方法都会为命名空间冲突提供额外的机会。我只想要一种方法来激活插件本身,所以我期待重构。避免污染jQuery命名空间的最佳插件开发实践?

$('ol#tree').tree(options) // just a single jQuery method for my plugin is fine… 
$('li#item4').moveNode('li#item6') // …however, we also have this supporting method 
$('ol#tree').appendNode(node) // …and this one 
$('li#item2').expandBranch() // …and this one, etc. 

将接口暴露给已激活的DOM元素及其不污染jQuery名称空间的子元素的一些做法是什么?

我玩过保存jQuery对象,当我创建树时会回来。

var tree = $('ol#tree').tree(); 

此树对象本身将被扩展以包含方法。不幸的是,由于树本身被有规律地操作,这会冒着让该对象的状态与父DOM元素及其子元素的状态不同步的风险。我不确定在该对象中维护状态是否值得,因为DOM本身将始终具有当前状态。

$('ol#tree').tree() 
$('ol#tree').tree.appendNode(node) 
$('ol#tree').tree.item('li#item2').expandBranch() 

你如何处理这个问题:

我还使用一个命名空间(通过约翰Resig的Space plugin)考虑?你能指点我一些现有的插件来解决这个问题,我的代码可以学到吗?

回答

2

使用一个简短而清脆的名字!不是无聊的,但例如nicetree(嘿,这只是一个想法)!将界面放入名称中。像这样:

$("ol#tree").nicetree.appendNode(node); 
$("ol#tree").nicetree.item("li#item2").expandBranch(); 

另一个想法是按照您的建议返回的对象,但不更新此对象。该对象只是对真实对象或DOM的引用。这增加了一层间接性,这可能会或可能不会被您接受。

我作为一个插件用户会喜欢这两种解决方案,但更喜欢第一个稍微。

+0

我已经看到了这种方法,并喜欢它。但是,我已经解决了一些问题,如我在答案中看到的。 – Mario 2009-12-01 23:38:15

+0

没有理由你不能这样做。 – 2010-01-21 17:32:01

+1

appendNode()或item()方法如何引用包含所选元素的jQuery对象(在本例中为$(“ol#tree”))?看起来好像它遇到了这样的问题:这些函数中的“this”并没有让你找回jQuery对象,只是nicetree对象,它是一个从jQuery原型创建的静态对象。 – thomasrutter 2010-10-07 12:59:58

0

这就是我想出了,因为我问:

MarioWare = { 
    Tree: { 
    Methods: { 
     nodes: function(){ 
     var selected = null; 
     var context = this[0]; 
     if (selector === undefined) // tree.nodes(); 
      selected = $('li', context); 
     else if (typeof selector == 'string') // tree.nodes('li:first,li:last'); 
      selected = $(selector, context); 
     else if (typeof selector == 'number') // tree.nodes(2); 
      selected = $('li', context).eq(selector); 
     return MarioWare.$node(selected); 
     }, 
     appendNode: function(){...} 
    } 
    }, 
    $tree: function(selector){ 
    return $.extend($(selector), MarioWare.Tree.Methods); 
    }, 
    Node: { 
    Methods: { 
     select: function(multiSelect) {...} 
    } 
    }, 
    $node: function(selector){ 
    return $.extend($(selector), MarioWare.Node.Methods); 
    } 
} 

通过这种方式,就像一些在的Prototype.js找到实用方法:

var $tree = MarioWare.$tree; //shortcut 
var $node = MarioWare.$node; //shortcut 
var tree = $tree('ul:first'); 
var nodes = tree.nodes(); 
nodes.eq(0).select(); 

它总是需要一个实用工具访问者(例如$ tree,$ node),但它可以防止jQuery名称空间受到污染。我喜欢这个访问者澄清我们正在处理的内容 - 例如树或节点。

+0

为此,所有返回值必须用适当的实用方法重新包装结果。例如“select”将返回“$ node(result)”。我还必须重写基本的jQuery函数(如“eq”)来返回包装结果。啊!有点笨重 - 但它有效。 – Mario 2009-12-02 19:04:37