2014-01-28 25 views
1

我有一個使用KnockoutJS的ASP.NET MVC4 SPA web應用程序,這有點尷尬,因爲據我瞭解,當頁面最初加載到SPA時通常沒有數據直到AJAX調用檢索它。當我嘗試使用像data-bind="with: myData"這樣的屬性綁定塊中的各種數據時,該節點內的整個DOM被清空,直到myData變爲有效,這讓我感到緊張,如果某些腳本可能依靠這些元素可用於附加腳本到或某物。頁面塊在加載過程中消失並重新出現也很糟糕。所以,我設計了with結合,以防止後代綁定,如果該值爲空,目前看起來像這樣的變化:KnockoutJS「與」綁定在模型可用之前

ko.bindingHandlers.safeWith = { 
    'init': ko.bindingHandlers.with.init, 
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if ((value != undefined) && (value != null)) 
      ko.bindingHandlers.with.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    } 
}; 

然後,我只是用safeWith而不是with,以確保我沒有按DOM」在等待myData被填充時不會消失。

我的問題是:

  1. 這是利用基因敲除SPA的一個共同的問題,如果是這樣,它是如何正常處理?
  2. 我處理這個安全問題的方式或者是否有我以某種方式應用重複事件/綁定的風險或我不知道的一些風險?
  3. 我很驚訝我在漫遊有關網絡學習淘汰賽和相關技術,我沒有跑過這個。 傾向於有充分的理由讓DOM的部分在它們綁定到的對象爲空時消失;我是否試圖保持它的錯誤?

回答

1

我已經實現,通過推遲綁定邏輯,直至觀察到其內部具有一個有效值顯著改善了我們結果的自定義bindIf綁定處理程序:

ko.bindingHandlers.bindIf = { 
    'init': function (element, valueAccessor) { 
     return { 'controlsDescendantBindings': true }; 
    }, 
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (!$(element).data("bindIfPassed") && valueAccessor()) { 
      $(element).data("bindIfPassed", true); 
      ko.applyBindingsToDescendants(bindingContext, element); 
     } 
    } 
} 

應用於高級別節點是這樣的:

<div data-bind="bindIf: myObservable()"> 
0

我可以看到爲什麼你不想讓帶有綁定元素的DOM消失的原因,但它們很少。幾乎所有這些都涉及DOM操作,需要一定的時間。例如,在顯示視圖時,將焦點設置爲第一個輸入字段。有時候,這種問題的解決方法並不太好,在這種情況下,像你這樣的綁定會幫助你很多。

一般來說,

  1. 我想這一定程度上是一個常見的問題。你提到幾個 問題:依賴這些元素的腳本:在 一般情況下,我會迴應你的腳本是錯誤的。現在這是一個 有點苛刻,但我確實覺得它有點代碼味,如果某個DOM元素不是 可用,那麼您的腳本會崩潰。其次,你覺得dom的一部分消失了,並且 重新出現並不是什麼好事。在這種情況下,也許你應該 '重置'在你的綁定到 'null'以外的可觀察。創建任何對象的「空白」實例,通常將 轉換爲可觀察對象,並使用該對象而不是null,以便DOM 保持不變。如果這不是一個選項,那麼你的場景不是 確實是一個綁定的用例(並且你自己的綁定對於這樣的場景確實是一個有用的例子)。
  2. 我不完全確定。我試圖查看綁定,但由於某種原因,我無法在Knockout代碼中找到它。它很容易測試,只需在綁定中設置一個事件綁定,然後改變observable的值幾次。看起來有點擔心,當值爲undefined/null時,從不更新with-binding:我可以想象這很容易導致進一步綁定DOM的錯誤。
  3. 確實有很好的理由,特別是在單頁面應用程序中。我正在用Knockout做一個非常大的應用程序作爲SPA。通過正確使用with-binding和清理視圖時的視圖模型,我可以很容易地管理內存(其中DOM節點是很重要的部分),即使視圖緩存在前端。如果我們沒有相關數據不存在時卸載DOM節點的機制,應用程序運行速度會非常緩慢。這是一個我非常喜歡的數據驅動方法:所顯示的DOM部分是相關的部分,因爲數據在那裏。
+0

如果您搜索''with''的knockout JS文件(包括引號),您將看到它是通過調用'makeWithIfBinding'創建的。 ''with''只在我的knockout.js版本中出現過一次('knockout-2.2.0.debug.js')。我知道想要移除不適用的DOM部分,但是您是否也必須處理尚未加載模型的DOM的某些部分,但是當頁面加載完成時它會被加載?在這些情況下你會遇到這個問題嗎? – BlueMonkMN

+0

偶爾遇到它,但我通常在完成加載數據之前避免顯示視圖。你使用單頁面應用程序還是多頁面? –

+0

我正在對一個應用程序進行原型設計,我期望每個主要功能都是一個小型SPA。在頁面中加載新記錄將使用AJAX調用來檢索新數據,而不是重新加載整個頁面,但導航到另一個函數將加載一個全新的頁面。 – BlueMonkMN