2

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=

http://liveweave.com/QmJeaH

2 Answers 2

1

Your binding handler should

  • set up its state in init
  • pass everything through to the 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

Sign up to request clarification or add additional context in comments.

Comments

1

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>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.