2009-12-01 88 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