Reputation: 8921
I am following the example here to create a custom binding. The property to be updated is obtained like this in the documentation:
var value = valueAccessor();
value(false);
In my code, a table is bound to an array of objects using knockout's foreach
binding.
<tbody data-bind="foreach: {data: sites, as: 'site'}">
<td class="siteid" data-bind="text: site.siteid"></td>
<td class="expirydate" data-bind="datepicker: site.expirydate"></td>
et cetera
The table seems to be correctly populated with data. The values are all in the right place.
The objects in the array have a few string properties and a couple of dates, so several of the table cells have jQuery UI datepickers attached to them. Here's the custom datepicker binding code I'm using, which I found here on SO, though I don't have the reference handy (it was from a response by Mr Niemeyer, as I recall).
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
$el.datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
var newVal = $el.datepicker("getDate")
observable(newVal);
// a breakpoint is set at this location
});
.
.
. <snip>
The code crashes on observable(newVal);
However, if I change
var observable = valueAccessor();
to
var observable = valueAccessor;
then the code runs without error. But when I examine the value in observable
afterwards, at the breakpoint location, it does not contain the date value in newVal
; rather it contains the original date value.
And if instead of observable(newVal)
I try this instead:
allBindingsAccessor().value(newVal);
I get an error: " Object doesn't support property or method 'value'".
Upvotes: 1
Views: 990
Reputation: 6045
well yes it wont update the model sadly where Reasons Unknown .
But i made things work for me in different approach .
With CSHTML syntax :
<input type="text" data-bind="value:$data.CompletionDate,datePicker:true " />
Points i noticed :
-In data-bind if you remove value
and try keeping some custom binding like below model wont get update
<input type="text" data-bind="formatdate:$data.CompletionDate,datePicker:true " />
enter code here
-instead i tried using old fashioned way keeping value
intact and added Datepicker:true
whihc serves my purspose of binding and date selection .
My Datepicker binding handler
ko.bindingHandlers.datePicker = {
init: function (element, valueAccessor) {
var value = valueAccessor();
var value = ko.utils.unwrapObservable(valueAccessor()); //ko.unwrap based on version you use
if (value && typeof value === 'object') {
$(element).datepicker(value);
}
else {
$(element).datepicker(/* your default options here */);
}
}
}
Well above approach may or maynot solve your issue but its definitely a cheery in mouth .
Upvotes: 0
Reputation: 8921
The individual properties of the objects in my array of objects were not observables.
So, when I add a new site object to my Sites array, I needed to be doing this:
var Site = function(siteid, sitename, expirydate) {
this.siteid=siteid;
this.sitename = ko.observable(sitename);
this.expirydate = ko.observable(expirydate);
}
function SitesViewModel(){
var self=this;
self.sites = ko.observableArray([]);
self.sites.push( new Site ( ......) );
}
so that valueAccessor()
returns an observable, not simply an integer or string or date object, as the case may be.
Upvotes: 1