2010-02-14 40 views
6

我決定需要提高我的javascript編程技能以及我的面向對象技能。我目前正在閱讀一些書籍,但有時很難在沒有看到一些實際案例的情況下理解這個理論。所以,我有一個關於「最佳實踐」的以下場景的理論問題...面向對象的JavaScript最佳實踐問題:我應該如何配置我的對象以下

我想創建一個OO腳本,顯示從服務器檢索到的searchtag記錄列表。我也希望能夠編輯每個searchtag記錄。

目前我與jQuery庫有點幫助程序上這樣做:

我接受來自服務器searchtag記錄的JSON編碼的列表。它看起來像這樣:

[ 
    { "searchTagName" : "tagOne", "searchTagID" : "1" }, 
    { "searchTagName" : "tagTwo", "searchTagID" : "2" }, 
    { "searchTagName" : "tagThree", "searchTagID" : "3" }, 
    etc... 
] 

我直接轉儲到JSON到jTemplates創建相應的HTML,像這樣:

$("#searchTagList") 
    .setTemplateElement("template_searchTagList") 
    .processTemplate(searchTagData); 

最後,我希望它是可以修改每個searchtag與編輯 - 所以我在每個html元素上附加了一個預編譯就地編輯方法:

$(".searchTag").editInPlace(); 

這在程序上效果很好。也許最聰明的事情是單獨離開。 :)但是,爲了爭論,從面向對象的角度來寫這樣的東西的最好方法是什麼。

我應該有一個單獨的對象「searchTagList」,它具有上述每個步驟的方法嗎?

var searchTagList = 
{ 
    searchTagData: JSONdata, 
    renderList: function() { /*send to jTemplates */ } 
    bindEdit: function() { /* attach edit-in-place */ } 
} 

或者那是不正確的? (看來我所做的只是將程序功能包裝在一個對象中。)我是否應該將JSON數據解析爲每個searchtag的實例,然後將各個方法附加到每個searchtag? (這看起來像是一個很大的開銷,沒有增益。)

如果我好像在挑毛髮一樣,事先道歉。但我真的很想把這些東西放在我的腦海裏。

感謝,

特拉維斯

回答

2

實際上,您發佈的jQuery的例子不是程序性的,它們是面向對象的。具體而言,它們是來自流程編程學院的OO設計的可鏈接對象的實現。

程序性會是這樣的:

var el = cssQuery("#searchTagList"); 
var templateObject = makeTemplate(el,"template_searchTagList"); 
processTemplate(templateObject,searchTagData); 

功能會是這樣的:

processTemplate(
    makeTemplate(
     cssQuery("#searchTagList"), 
     "template_searchTagList" 
    ), 
    searchTagData 
); 

的jQuery已經做客觀化DOM API的一個不錯的工作。將它用作您自己的OO DOM庫的靈感是可以的。另一個我推薦你看的是YUI3(YUI2非常程序化)。

具體而言,jQuery和YUI3的一般模式是:

nodeListConstructor(query_string).nodeMethods(); 

凡它們限定一個面向對象的類節點對象環繞DOM HTML元素,然後另一個OO風格節點列表對象,以允許你批量處理節點。這在我看來是一個很好的設計模式。

+0

感謝您的回覆。我應該澄清。當我的意思是程序性的,我的意思是我在全球空間中有三種不同的功能。一個來處理從服務器檢索JSON。一個將JSON轉換爲html。還有一個最終的功能是將一個編輯就地方法附加到html節點上。確實,這些函數中的每一個都在內部使用OO jQuery技術。但我更關心組織三個更高層次的功能的最佳方式,它們目前看起來非常程序化 - 即它們是否應該全部包裹在一個對象中。我會看看YUI3,謝謝。 – Travis 2010-02-15 20:18:58

1

你可以在這裏使用Javascript模塊模式效果很好。

根據這一模式,將searchTagList定義將改變爲:

var searchTagList = function() { 
    searchTagData: JSONdata; 
    return { 
    renderList: function() { /*send to jTemplates */ }, 
    bindEdit: function() { /* attach edit-in-place */ } 
    }; 
}(); 

兩個功能renderList和bindEdit仍然能夠訪問searchTagData但仍然無法訪問代碼之外searchTagList模塊。

觀察到匿名函數立即執行並返回一個包含兩個公共方法(renderList和bindEdit)的對象,這些方法在私有成員searchTagData上形成closure

你可以閱讀更多關於模塊模式here

+1

感謝您的信息。我一直在玩模塊模式。但是我發現速度很快(不是在上面的例子中,而是在實際的生產代碼中),我有時會遇到一些情況,讓私有方法調用一個公共方法會很方便 - 而且這種方法不起作用。也許這只是我設計的不好的設計...... :) – Travis 2010-02-15 20:20:37

+0

在模塊模式中調用一個私有方法的公共方法是不可能的,因爲公共成員在私有成員上形成一個閉包,而不是相反。這讓我感到很震驚,而我之前從未想過這種情況。謝謝。 – ardsrk 2010-02-16 11:12:30

+1

@Travis,如果您需要使用私有方法調用公共方法,只需按照私有方法的方式定義公用方法,然後將其按名稱添加到返回的對象中,而不是作爲匿名函數。 – 2010-02-16 14:47:36