2012-02-08 37 views
8

每當通過Knockout.JS更新DOM時,我需要運行一段jQuery UI代碼。我意識到這可以使用自定義綁定來完成,但是這似乎與特定的viewmodel有關,我想在全局範圍內執行此操作,以便在發生任何視圖模型時觸發它?假設我總是希望所有帶有類'needsdate'的文本框都使用JQuery datepicker,而不是將它添加到每個視圖模型中,如果我能夠在全局範圍內完成這項工作,那將是非常不錯的。Knockout JS event for any viewmodel dom update

這可能嗎?

+0

你能解釋一下你的情況嗎?通常,您將使用綁定到可觀察對象的自定義綁定。當這個observable發生變化時,綁定會運行任何jQuery UI代碼對綁定所在的元素都是必需的。有一種方法可以做你正在問的東西,但是我想在提出這個用例之前先聽聽更多關於這個用例的信息,因爲這不是正常的方法。 – 2012-02-08 03:01:41

+0

更新了我的主帖:可以說我總是希望在所有帶有類'needsdate'的文本框上使用JQuery datepicker,而不是將其添加到每個視圖模型中,如果我可以在全局範圍內執行它,那將非常棒。 這有幫助嗎? – RodH257 2012-02-08 07:19:16

+0

如果你沒有綁定到視圖模型,那麼可能你不需要爲此敲除。 – 2012-02-08 07:25:02

回答

7

如果您不打算動態添加/刪除元素,那麼您可以將它們正常連接。但是,如果您正在使用動態內容(如使用可修改項目的observableArray),那麼您有幾個選項:

1-與答案here一樣,您可以創建自定義綁定。如果你不想價值在您的視圖模型屬性綁定,那麼你就可以簡化結合是這樣的:

ko.bindingHandlers.datepicker = { 
    init: function(element, valueAccessor) { 
     //initialize datepicker with some optional options 
     var options = ko.utils.unwrapObservable(valueAccessor()); 
     $(element).datepicker(options); 

     //handle disposal (if KO removes by the template binding) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).datepicker("destroy"); 
     }); 
    } 
}; 

你將它放在一個元素上,如:

<input data-bind="datepicker: { minDate: new Date() }" />

2-另一種選擇是使用template(和foreach它使用template)的afterRenderfunctionality新內容之後被渲染到線了您的datepickers。

0

我創建了一個refreshJQuery()函數,可以一次性應用我所有的強壯行爲。當我在我的視圖模型中訂閱observables來更新我的模型時,我會調用這個函數。並在頁面加載一次。

function refreshJQuery() { 
    $(".draggable, .droppable, .resizable").each(function() { 

     var $element = $(this); 

     if ($element.hasClass("draggable") && !$element.data("init-draggable")) { 
      $element.data("init-draggable", true).draggable(dragBehavior); 
     } 
     if ($element.hasClass("droppable") && !$element.data("init-droppable")) { 
      $element.data("init-droppable", true).droppable(dropBehavior); 
     } 
     if ($element.hasClass("resizable") && !$element.data("init-resizable")) { 
      $element.data("init-resizable", true).resizable(resizeBehavior); 
      $(this).children().fadeTo(2000, 0); 
      $element.hover(function() { 
       $(this).children().fadeTo(200, 1); 
      }, 
      function() { 
       $(this).children().fadeTo(750, 0); 
      }); 
     } 
    }); 
}; 

然後我用它如下,雖然我已經確定了其他2個觀測我需要從還調用這個函數:

this.updateTime = function() { 
    service.updateBookingTimes(this.id(), this.startDate(), this.endDate()); 
    refreshJQuery(); 
}; 

this.startDate.subscribe(this.updateTime, this); 
this.endDate.subscribe(this.updateTime, this); 

我也實現@ RPNiemeyer的字段級的JQuery解決方案訂閱,所以除了他的日期選擇器樣本外,我還有類似的代碼,它可以重新應用$.button()<a>標籤,另一個將複選框轉換爲iPhone風格的開關。