Reputation: 14416
I have a textbox bound to a custom binding. For the sake of an example all it does it wrap the control with a bordered div. I then pass the bound observable to the value binding but it is not updating the underlying observable as I'd expect.
=Html=
<body data-bind="with: model">
<textarea data-bind="wrapbox: someval" ></textarea>
<textarea data-bind="value: someval" ></textarea>
<div data-bind="text: someval"></div>
</body>
=Js=
ko.bindingHandlers.wrapbox = {
update: function(element, valueAccessor)
{
var value = ko.unwrap(valueAccessor());
$(element).wrap("<div class='border' />");
return ko.bindingHandlers.value.update(element,
function(){return value; });
//return ko.bindingHandlers.value.update(element,
// valueAccessor()); <---- tried this too.
}
};
var viewmodel = function() {
var model = {};
model.someval = ko.observable();
return {
model: ko.observable(model)
};
}();
ko.applyBindings(viewmodel);
=Example=
Upvotes: 2
Views: 979
Reputation: 10328
Make sure that you set up your binding in an init
handler, which in contrast to update
runs only once and should contain your $.wrap
.
Along these lines, if you wrap another binding, make sure to call both its init
and update
where appropriate, and pass along all arguments it may require:
ko.bindingHandlers.wrapbox = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).wrap("<div class='border' />");
return ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
return ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
};
var viewmodel = function() {
var model = {};
model.someval = ko.observable('');
return {
model: ko.observable(model)
};
}();
ko.applyBindings(viewmodel);
.lw { font-size: 60px; }
.border{
border: 3px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="with: model">
<textarea data-bind="wrapbox: someval" ></textarea>
<textarea data-bind="value: someval" ></textarea>
<div data-bind="text: someval"></div>
</div>
Upvotes: 1
Reputation: 136074
Your binding handler should
init
value
binding directly in both init
and update
Code:
ko.bindingHandlers.wrapbox = {
init: function (element, valueAccessor, allBindingsAccessor,
viewModel, bindingContext) {
$(element).wrap("<div class='border' />");
ko.bindingHandlers.value.init(element, valueAccessor,
allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor,
viewModel, bindingContext) {
ko.bindingHandlers.value.update(element, valueAccessor,
allBindingsAccessor, viewModel, bindingContext);
}
};
Updated your example: http://liveweave.com/Yq1UPl
Upvotes: 1