2010-06-07 53 views
1

我一直在閱讀關於jQuery中的自定義事件以及爲什麼應該使用它們,但我仍然清楚地忽略了這一點。有一篇非常好的文章,我讀here有以下代碼示例;jQuery中的自定義事件和事件池 - 有什麼意義?

function UpdateOutput() { 
    var name = $('#txtName').val(); 
    var address = $('#txtAddress').val(); 
    var city = $('#txtCity').val(); 

    $('#output').html(name + ' ' + address + ' ' + city); 
} 

$(document).bind('NAME_CHANGE ADDRESS_CHANGE CITY_CHANGE', function() { 
    UpdateOutput(); 
}); 

$('#txtAddress').keyup(function() { 
    $(document).trigger('ADDRESS_CHANGE'); 
}); 
$('#txtCity').keyup(function() { 
    $(document).trigger('CITY_CHANGE'); 
}); 

有人能告訴我爲什麼我只是不直接調用UpdateOutput()函數嗎?它仍然會工作完全相同的方式,即

$('#txtAddress').keyup(function() { 
    UpdateOutput() 
}); 
$('#txtCity').keyup(function() { 
    UpdateOutput() 
}); 

非常感謝

+1

你所描述的是基於事件的編程,它具有相同的優點和缺點,任何編程風格有。 – jAndy 2010-06-07 10:59:04

回答

1

因爲您是該事件的一個客戶,即使您完全控制了整個應用程序。它有助於更​​好地解耦你的代碼。

作爲有興趣瞭解名稱,地址或城市更改時間的客戶之一,您正在更新屏幕某些部分的值。某些其他客戶端可能想要執行其他操作,如拉起所有相鄰城市,反向地址解析地址,在namesdatabase.com上進行名稱查找等等。

您仍然可以控制沒有事件的所有事件,並直接調用多個函數或將所有內容都放入自己的函數中,但添加事件僅根據事件的類型將執行從需要完成的事情中分離出來,因此UpdateOutput沒有擔心從名字數據庫中提取姓名,只要對系統中定義的事件有一個基本的瞭解,並且他們代表的是什麼,則無需擔心在發生特定事件時自己調用所有必要的功能。

第二個原因是抽象。例如,刪除用戶帳戶可能會通過簡單的點擊觸發,但只需將其轉換爲更高級別的事件(例如DeleteAccount),當您考慮到可能會有數十或數百個或可能會變得更簡單和易於理解時即使在應用程序中也有數千個這樣的事件。在比「keyups」,「keydowns」,「mouseovers」等更高的抽象層次上工作(這在應用程序和背後的意圖中是毫無意義的),因此應用程序可以更容易管理大小增長。

+0

感謝您的回覆,我現在重讀了5次,但仍然無法看到爲什麼直接調用函數,即deleteAccount()並通過事件調用它,例如$(document).trigger('DELETE_ACCOUNT')然後調用deleteAccount()使我的代碼有所不同。 deleteAccount()仍然被調用任何方式?我現在一直在閱讀大量文章,並希望這筆錢會下降,因爲它讓我發瘋,看不到它的好處。 – screenm0nkey 2010-06-07 14:39:45

+0

我認爲理解這一點的更好方法是編寫一個在UI上非常豐富的小應用程序,然後看看事情能夠得到多少。在上面的例子中,如果你直接依賴於DOM事件,你可以從'click - > function 1,function 2,..''映射,並且有很多這樣的映射。通過自定義事件,您可以獲得一個抽象級別,例如'AccountDeleted - > function 1,function 2,..'。就實際完成情況而言,沒有任何變化,但這只是一種更易於管理的方法。 – Anurag 2010-06-07 23:09:41

+0

感謝您的幫助Anurag。 – screenm0nkey 2010-06-08 09:31:57

4

由於your article打頭:

殊不知,越是依賴你的系統有,就越難保持那個系統是。 Javascript也不例外 - 如果不正確地完成,跨複雜用戶界面的編排操作可能是一場噩夢。

使用事件中移除(部分),這些依賴關係:

  • 當事情發生(一鍵釋放/時),本次活動的通知發送,沒有知道是否有人有興趣目前還是沒有。
  • 如果有人有興趣在一定的情況下,他可以訂閱它,沒有知道爲什麼這個事件被觸發(釋放鍵)

兩個子彈是獨立的,第一通知和第二響應。去除一個對另一個的功能無關緊要。擁有多個事件觸發/訂閱事件也很容易(也由於缺少依賴關係)。

+0

所以你說的是,如果我要觸發一個事件,沒有功能被綁定到事件那麼會有沒有錯誤,即$(document).trigger('ADDRESS_CHANGE'),但如果我直接調用函數,那麼會導致錯誤? – screenm0nkey 2010-06-07 14:10:09

+0

是的,除非你只會直接調用錯誤,如果該函數沒有定義的話。我想,當事件被觸發時,可以將多個函數綁定到單個事件(反之亦然),並且所有事件都被觸發。 – Veger 2010-06-07 15:39:30

+0

感謝您的幫助Veger。我慢慢開始理解這些好處,但如果我有一個豐富的UI項目,這將有所幫助。 – screenm0nkey 2010-06-08 09:31:36

1

直接連接UpdateOutput()調用是完全合理的。通常,很難用簡單的例子來表示自定義事件池提供的抽象需求。

但是,當直接調用UpdateOutput時,(可以說)有兩個可維護性問題(同樣取決於使用情況)。第一個問題是在許多地方重複UpdateOutput()調用。這使得重構函數(特別是那些帶參數的函數)在更改時非常困難。通過事件池,您可以在將數據傳遞給函數之前進行數據準備,這對於不同的代碼塊調用相同函數時非常有用。隨着ajax沉重的網絡應用程序,控制函數調用是非常重要的。

其次,您可能需要爲同一個事件調用多個函數。想象一下,除了UpdateOutput()之外,還有一些驗證函數需要被解僱。或者,當用戶更新郵政編碼時,會觸發某些地圖api以顯示某些內容或任何可能發生的其他功能(重點在於您可能在簡單的keyup()事件中調用了許多功能。對於只需調用多個函數的非常大的代碼塊,如果需要條件邏輯,它們可能會失去控制。通過事件池重寫,您可以更好地控制UpdateOutput之類的函數被調用的方式,因此您不必你不需要追蹤大量文件中的方法,你可以簡單地看到cal的綁定事件

+0

沒問題 - 我寫了你鏈接的文章。還有一篇後續文章,但現在已經很老了。我認爲您可以更有效地管理像knockoutjs這樣的更高級別框架的事件。 – mhamrah 2011-06-28 12:55:53