knockoutjs - 自定义绑定嵌套在模板内,attr尚未绑定自定义绑定调用

时间:2016-01-26 14:43:36

标签: javascript jquery knockout.js

我在模板中有自定义绑定。

自定义绑定涉及使用绑定到模板的attrs呈现的属性。

<script type="text/html" id="mc-radio-template">
        <!-- ko foreach: Values -->
        <div class="rounded_col" data-bind="complexRadio: $parent.Value">
            <label data-bind="text: Description"></label>
            <input type="radio" style="visibility:hidden" data-bind="attr: { 'name': $parent.Name, 'value': Value}" />
        </div>            
        <!-- /ko -->
    </script>

complexRadio涉及输入的值,该值由模板使用attr绑定呈现。

ko.bindingHandlers.complexRadio = {
    init: function (element, valueAccessor) {
        // Get radio button located inside this div
        var radio = $(element).find('input[type="radio"]');
        var isDisabled = !!radio.attr('disabled');

        var value = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);

        if (valueUnwrapped === true)
            valueUnwrapped = 'true';

        if (valueUnwrapped === false)
            valueUnwrapped = 'false';

        value(valueUnwrapped);

        // When div is clicked, check the radio and trigger radio change event
        if (!isDisabled)
            $(element).click(function () {
                radio.prop('checked', true);
                radio.change();
            });

        // When radio button is checked, update the viewModel property!!
        $(radio).change(function () {
            if (radio.prop('checked'))  // only if it was changed to checked
            {
                // Set viewModel property to value of the radio button that was clicked
                var value = valueAccessor();

                value(radio.val());
            }
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);

        if (valueUnwrapped === true)
            valueUnwrapped = 'true';

        if (valueUnwrapped === false)
            valueUnwrapped = 'false';


        // Get radio button located inside this div
        var radio = $(element).find('input[type="radio"]');

        // Set radio to be checked or unchecked
        var shouldBeChecked = valueUnwrapped == radio.val();
        if (shouldBeChecked)
            radio.parent().addClass('active');
        else
            radio.parent().removeClass('active');
    }
};

我的问题是complexRadio init在模板呈现value属性之前发生。

在这一行 -

var shouldBeChecked = valueUnwrapped == radio.val();

radio.val()不是模板完成渲染后渲染的那个。 这会导致无线电的开始状态被取消选中。

如何在渲染结束后强制自定义绑定运行? 或许 - 如何使用js添加自定义绑定,以便我可以在afterRender回调中添加它。

1 个答案:

答案 0 :(得分:1)

您在广播中绑定了value,并且您正在使用jQuery访问其value属性,但是在应用外部绑定之后,广播才会被绑定。无线电没有被渲染,这不是真的,它只是没有约束。

解决方案是让外部绑定控制绑定所包含的无线电。请参阅the documentation on descendant bindings