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/trueに更新されないようです。私は何かが足りないのですか?

4

5 に答える 5

6

すべてのサブアイテムがチェックされていない場合でも、[すべてのタイプを選択]チェックボックスを中間として表示することを検討している場合は、次のような単純なバインディングを使用できます。

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"/>

これは、計算されたobservableselectallの例で動作していることを示すフィドルです https://jsfiddle.net/deannorth/crqwac12/

于 2017-06-23T11:19:50.443 に答える
5

@Fodagusによる回答は、Knockout <= 2.3.0で機能しますが、Knockout>=3.0.0ではko.bindingHandlers.checked.update未定義です。

これはKnockout3.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;
            }
        }
    };

何か足りないものはありますか?

于 2014-07-09T16:02:35.677 に答える
4

Initを呼び出していません。

アップデートで行ったように、nullableCheckedinit関数をチェックインするためにinit関数をプロキシするだけです。

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);
    }
};

initがないと、チェックボックスに「クリック」バインディングを設定して、何かが変更されたことをノックアウトに通知することはできません。デバッグコード(http://knockoutjs.com/downloads/knockout-2.2.1.debug.js)を見ると、initがjQueryを使用して、チェックボックスに「クリック」イベントを設定して更新していることがわかります。値が変化したときに観察可能。

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/

于 2013-03-26T15:42:49.303 に答える
2

以上の新しいバージョンknockout 3.0.0checkboxバインディングハンドラのupdateメソッドが削除されました。したがって、がクリックされるたびにupdateメソッドをトリガーする関数にをclick event作成する必要があります。以下は、をに変換するためのバインディングハンドラーの例です。initcheckboxjquery checkboxuniform 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));
    }
};
于 2014-08-13T09:17:57.297 に答える
1

checkedハンドラーは、値を保持していたオブザーバブルではなく、格納された値へのアクセサーを受け取ります。したがって、observableはハンドラーによって引き起こされた値の変更を取得することはありません。バリューアクセサーをそのまま渡すことができるはずだと思います。

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);
    }
};
于 2013-03-26T15:32:37.573 に答える