2012-02-26 23 views
0

舉個例子來說,情況使用knockoutjs元素:安裝行爲由knockoutjs創建

<div id="container" data-bind="foreach:containers"> 
    <li class="complex-element">...</li> 
</div> 

現在我想一些複雜的行爲附加到complex-element。我怎麼做?我不能直接將事件附加到複雜元素上,因爲它們是在運行時動態創建和刪除以匹配視圖模型的。所以,當我看到它:

我可以用data-bind="click:..." s和data-bind="mouseenter:..." s來謎語我的html,但我寧願避免這個,如果我可以。也許我太植根於我的老MVC的方式,但加入open()select(),或dragStart()功能和isOpenisSelectedisDragging觀察的標誌到我的視圖模型只是讓一個爛攤子,我的直覺告訴我,作爲應用程序變得更大這一觀點模型將變得難以管理。如果可能的話,我寧願保留我的數據和我的陳述。

或者我可以使用jquery委託來將事件附加到固定的東西上。喜歡的東西:

$("#container").on('click', '.complex-element button.open', function(e) { 
    var elem = $(e.target).parents('.complex-element'); 
    ... 
}); 

但是,這是行不通的應用程序變得更加複雜,因爲如果容器本身包裹在只登錄(<div id="wrapper" data-bind="if:isLoggedIn">...</div>)所示的元素會發生什麼。我不妨將所有事件都綁定到身體上,這是一個災難的祕訣。

我發現了一個非常酷的文章knockmeout.net(http://www.knockmeout.net/2011/07/another-look-at-custom-bindings-for.html),提倡使用自定義敲除綁定驅動複雜的行爲,這似乎是一個像自動完成或日期選擇器的小部件般行爲的一個很棒的解決方案,但簡單的老式控制器呢...這會工作嗎?

我想,畢竟,我的問題很簡單:有沒有人在一個非常大的Web應用程序上使用Knockoutjs?你是怎麼做到的?

+0

我很想知道你是如何實現你的框架的。我們正在研究一個單頁面應用程序,該應用程序實現了一種MVVMC概念,這個概念是在閱讀這個博客系列之後開始的:http://blog.monnet-usa.com/這使得我們所有的viewModel都是分開的,大部分都不知道彼此。他們在控制器內互相訂閱。它變成了一個非常易於管理的源代碼佈局。特別是當與外部模板引擎一起使用時(爲了保持我們的主要標記清潔,直到需要加載某個模型)。雖然我開始看到由於行爲而導致的modelView膨脹。 – 2012-03-23 04:11:04

+0

@BrandonWittwer:我會看看那個博客。我沒有找到!謝謝。我仍在思考這個問題。我幾乎每天都從一個巨大的MVVM粉絲身上翻轉到想要全部投入,並從像Nicholas Zakas談論的更加結構化的模塊模式開始(http://www.youtube.com/watch?v=vXjVFPosQHw)。儘管這兩種方法都不適合我。 MVVM具有「行爲邏輯到哪裏」的問題,當處理數據比天氣和股票更復雜且更相互關聯時,嚴格的模塊模式會分崩離析。如果我知道了,我會讓你知道... – nicholas 2012-03-24 21:07:08

回答

2

你可以使用不同的jQuery綁定:

$(document).on('click', '#container>.complex-element button.open', function(e) { 
    var elem = $(e.target).parents('.complex-element'); 
    ... 
}); 

這工作,如果#container不存在。

在社區中正在進行一些工作,使淘汰賽的綁定不顯眼,易於編寫。現在,淘汰賽爲您提供dataFor()可以在這裏看到:Using unobtrusive event handlers或者您可以使用這樣一個小圖書館:Introducing the Knockout.Unobtrusive Plugin

+1

我也在重寫knockout.unobtrusive使用KO v2綁定提供程序模型的過程。這是一個WIP分支:https://github.com/bsatrom/Knockout.Unobtrusive/tree/ko-v2 – 2012-02-28 16:17:30

2

如果你需要從在foreach一些渲染的元素執行任意的JS,你可以使用afterAdd回調

<div id="container" data-bind="foreach: { data: containers, 
       afterAdd: somefunction }"> 
    <li class="complex-element">...</li> 
</div> 

我用KO上真正大的web應用程序和我去有關管理複雜性的方式是

  1. 拆分出來的ViewModels到一個單一的主命名空間內獨立使用的命名空間。
  2. 爲複雜的可重用行爲編寫自定義綁定。
  3. 創建實體模型類,封裝大多數重要的業務邏輯,類似於骨幹模型。
  4. 確保viewModels完全查看特定視圖和相關視圖(由第3點提供幫助)
  5. 保持所有jquery選擇器爲最低限度,我覺得編寫任何全局代表都很骯髒,但有時候需要它們。

希望這會有所幫助。