2014-02-28 72 views
3

應用可見的綁定我正在寫一個自定義綁定,但作爲它的一部分,我需要通過javascript應用可見綁定的數據綁定。似乎沒有什麼問題可以讓它在前面工作,但是當正在使用的observable被更新時,綁定不會被重新評估。應用可見的綁定與knockout

在查看KO的源代碼時,沒有init事件,所以不確定是否在某些圖層上發生了某些空間魔術,以便重新評估可觀察變化的dom元素,但我無法找到此信息。

那麼,有沒有建立一個人工結合其重新評估,或者我需要創建自己的訂閱回調將一些特定的方式重新評估可見約束力?

這裏是我使用的代碼:我知道我可以寫我自己的顯示和隱藏的邏輯

ko.bindingHandlers.visible.update(element, isVisibleObservable, allBindingsAccessor, viewModel); 

,但我認爲這將是對乍一看容易使用現有的綁定,以便做它在引擎蓋下。

這裏是代碼的使用場景的一個簡單的例子:

ko.bindingHandlers.someCustomBinding = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var allBindings = allBindingsAccessor(); 
     var customBindings = allBindings.someCustomBinding; 
     var someReferencedElement = $(customBindings.target)[0]; 

     var isVisible = (customBindings.isDefault) ? true : false; 
     var visibleObservable = ko.observable(isVisible); 
     knockout.bindingHandlers.visible.update(someReferencedElement, visibleObservable, allBindingsAccessor, viewModel); 

     element.onclick = function() { 
      var toggledValue = !visibleObservable(); 
      visibleObservable(toggledValue) 
     }; 
    } 
}; 

我已經很大程度上簡化了的情況下,參數等,從而去除驗證,但應該強調的主要用途和問題。當我用自定義綁定單擊元素時,它會切換值(正如我可以在調試器中看到的那樣),儘管它不更新被引用的DOM元素的可見性。

+0

你有更多的代碼可以共享,所以我們可以嘗試重現該問題? – Tanner

+0

我不確定這是一個問題還是按預期工作,我可以提供更多信息,但上面顯示使用的癥結所在,將添加一個包裝以給出更多關於如何使用它的指示。 – Grofit

回答

1

退房這個職位 -

Reapply bindings in knockout

的問題是,您可以添加新的綁定到淘汰賽,並迫使他們重新評估,但你正在嘗試做的是應用結合到現有的綁定並清理節點並重新評估,這是我鏈接的問題中顯示的灰色區域。在這一點上,我會實現一個自定義綁定處理程序,以便在那裏使用show/hide邏輯來執行您正在嘗試執行的操作,直到找到更穩定的解決方案。

你可以只包含的代碼到您的自定義綁定處理程序現在 -

ko.bindingHandlers['visible'] = { 
    'update': function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     var isCurrentlyVisible = !(element.style.display == "none"); 
     if (value && !isCurrentlyVisible) 
      element.style.display = ""; 
     else if ((!value) && isCurrentlyVisible) 
      element.style.display = "none"; 
    } 
}; 

如果你表現出一個更好的例子,包括你的綁定處理程序,我可以幫更新。

+0

是的,我最初想到這一點,因爲我需要jquery,所以我可以簡化它很多。我會再給它一段時間,再有任何其他好的反應,但這似乎是迄今爲止的贏家:) – Grofit

+0

當然,有一點要記住的是,當你確實實現它,確保你得到和解包裝的價值,如圖所示該綁定正確地訂閱了observable。 –

+0

是的,就像我說過的,我只是很快地嘲笑了上述情況,而忽略瞭解包和穿透價值的包裝。會給你答案,因爲看起來沒有簡單的方法讓更新綁定重新評估,而無需在我的更新方法中調用它。然而,你有一個鏈接,爲什麼重新應用綁定是不好的,所以它是很好的內容。感謝您的回答。 – Grofit

2

可見綁定update函數需要從您的update函數中調用,否則它將無法正常工作。只需創建一個更新功能並移動呼叫。此外,第二個參數是valueAccessor,而不是原始觀察到:

ko.bindingHandlers.someCustomBinding = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var allBindings = allBindingsAccessor(); 
     var customBindings = allBindings.someCustomBinding; 
     var someReferencedElement = $(customBindings.target)[0]; 

     var isVisible = (customBindings.isDefault) ? true : false; 
     var visibleObservable = ko.observable(isVisible); 
     var visibleValueAccessor = function() { return visibleObservable; }; 

     // store the stuff as data on the element so that 
     // it can be found in the update call 
     var data = { element: somereferencedElement, v: visibleValueAccessor }; 
     ko.utils.domData.set(element, "__customBinding", data); 

     element.onclick = function() { 
      var toggledValue = !visibleObservable(); 
      visibleObservable(toggledValue) 
     }; 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var data = ko.utils.domData.get(element, "__customBinding"); 
     knockout.bindingHandlers.visible.update(data.element, data.v, allBindingsAccessor, viewModel); 
    } 
};