当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - knockoutjs - custom binding nested inside template, attr not bound yet on custom binding call

问题描述:

I have a custom binding inside a template.

The custom binding involves attributes rendered with attrs bound to the template.

<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 involves the input's value which is rendered by the template using the attr binding.

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

}

};

my issue is that the complexRadio init happens before the value attribute is rendered by the template.

on this line -

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

radio.val() is not the one that's rendered after the template is done rendering.

This causes the beginning state of the radio to be unchecked.

How can I force the custom binding to run after the rendering is over?

Or maybe - how to add the custom binding using js so i can add it in the afterRender callback.

网友答案:

You have a value binding on the radio, and you're using jQuery to access its value attribute, but the radio isn't bound until after the outer binding is applied. It's not true that the radio isn't rendered, it just isn't bound.

The solution is to have the outer binding control the binding of the contained radio. See the documentation on descendant bindings.

分享给朋友:
您可能感兴趣的文章:
随机阅读: