2013-03-26 37 views
1

讓我們把它簡稱:這是我的淘汰賽定製用於把一個複選框,在不確定狀態結合。淘汰賽定製的不確定複選框綁定將無法工作

ko.bindingHandlers.nullableChecked = { 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value == null) element.indeterminate = true; 
     ko.bindingHandlers.checked.update(element, function() { return value; }); 
    } 
}; 

如果初始值是null一切工作正常,複選框被置於不確定狀態,但是當我點擊複選框它似乎並沒有相應地更新綁定屬性的值設置爲false /真。我錯過了什麼嗎?

+0

任何把jsFiddle放在一起給我們玩的東西的機會? – 2013-03-26 12:30:33

回答

4

你不叫Init。

簡單的代理託運您的nullableChecked初始化函數就像你在更新所做的初始化函數。

ko.bindingHandlers.nullableChecked = { 
    init: function(element, valueAccessor) { 
      ko.bindingHandlers.checked.init(element, valueAccessor); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value == null) element.indeterminate = true; 
     ko.bindingHandlers.checked.update(element, valueAccessor); 
    } 
}; 

沒有初始化,它從來沒有真正建立一個「點擊」複選框綁定告訴淘汰賽事情有了變化。如果您查看調試代碼(http://knockoutjs.com/downloads/knockout-2.2.1.debug.js),您會看到init使用jQuery在複選框上設置「click」事件,以便在值更改時更新observable。

ko.bindingHandlers['checked'] = { 
'init': function (element, valueAccessor, allBindingsAccessor) { 
    var updateHandler = function() { 
     var valueToWrite; 
     if (element.type == "checkbox") { 
      valueToWrite = element.checked; 
     } else if ((element.type == "radio") && (element.checked)) { 
      valueToWrite = element.value; 
     } else { 
      return; // "checked" binding only responds to checkboxes and selected radio buttons 
     } 

     var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); 
     if ((element.type == "checkbox") && (unwrappedValue instanceof Array)) { 
      // For checkboxes bound to an array, we add/remove the checkbox value to that array 
      // This works for both observable and non-observable arrays 
      var existingEntryIndex = ko.utils.arrayIndexOf(unwrappedValue, element.value); 
      if (element.checked && (existingEntryIndex < 0)) 
       modelValue.push(element.value); 
      else if ((!element.checked) && (existingEntryIndex >= 0)) 
       modelValue.splice(existingEntryIndex, 1); 
     } else { 
      ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'checked', valueToWrite, true); 
     } 
    }; 
    ko.utils.registerEventHandler(element, "click", updateHandler); 

    // IE 6 won't allow radio buttons to be selected unless they have a name 
    if ((element.type == "radio") && !element.name) 
     ko.bindingHandlers['uniqueName']['init'](element, function() { return true }); 
}, 

編輯:這裏有一個小提琴:http://jsfiddle.net/cclose/NFfVn/

+0

實際上,要啓用代碼更新,如果值爲!= null – MarkO 2013-11-20 12:15:52

+1

,處理程序中的更新回調應該將不確定屬性設置爲false。這似乎適用於Knockout <= 2.3.0,但不適用於Knockout> = 3.0 0.0。任何想法爲什麼?有Knockout 3.0.0的解決方案嗎? – 2014-07-09 14:24:56

1

checked處理器接收一個訪問到被存儲,而不是可觀察這是保持的值的值。所以觀察者永遠不會得到處理程序引起的任何值更改。我認爲你應該能夠按照原樣傳遞值訪問器。

ko.bindingHandlers.nullableChecked = { 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value == null) element.indeterminate = true; 
     ko.bindingHandlers.checked.update(element, valueAccessor); 
    } 
}; 
4

通過@Fodagus答案可與淘汰賽< = 2.3.0,但在淘汰賽> = 3.0.0,ko.bindingHandlers.checked.update是不確定的。

我們發現,這爲我們工作在淘汰賽3.1.0:

ko.bindingHandlers.nullableChecked = { 
     init: function (element, valueAccessor) { 
      ko.bindingHandlers.checked.init(element, valueAccessor); 
     }, 
     update: function (element, valueAccessor) { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 
      if (value == null) { 
       element.indeterminate = true; 
      } 
      else { 
       element.indeterminate = false; 
      } 
     } 
    }; 

難道我們缺少什麼?

2

knockout 3.0.0及以上的新版本。 checkbox綁定處理程序中的更新方法被刪除。因此,只要點擊checkbox,您應該在init函數中創建一個click event觸發更新方法。下面是一個jquery checkbox轉換成uniform checkbox的結合處理程序的一個例子。

ko.bindingHandlers.checkedUniform = 
{ 
    init: function (element, valueAccessor) { 
     ko.bindingHandlers.checked.init(element, valueAccessor); 
     $(element).uniform().on('click', ko.bindingHandlers.checkedUniform.update); 
    }, 
    update: function (element, valueAccessor) 
    { 
     ko.bindingHandlers.checked.update(element, valueAccessor); 
     $.uniform.update($(element)); 
    } 
}; 
+0

你能解釋一下你制服的意思嗎? – 2017-05-02 03:52:32

0

如果有人在這裏尋找到有選擇的所有類型的複選框顯示爲中間如果不是它的所有子項的檢查,你可以使用一個簡單的像這樣

ko.bindingHandlers.indeterminateValue = { 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     element.indeterminate = value; 
    } 
}; 

結合,那麼你可以使用這樣的

<input type="checkbox" data-bind="checked: selectedAllProduce, indeterminateValue: selectedProduce().length > 0 && selectedProduce().length < produce.length" title="Select all/none"/> 

下面是一個小提琴顯示它工作的計算觀察到的全部選擇例如 https://jsfiddle.net/deannorth/crqwac12/