I need to bind a table with knockout, and I would like the table cell to get a different css class if the new value is higher or lower of the previous.
I have in mind different possibilities, such as storing the previous value in the bindingContext and have a function which returns the right class, but is it possible to add a custom binding handler which receives the previous value and the new value?
I need to bind a table with knockout, and I would like the table cell to get a different css class if the new value is higher or lower of the previous.
I have in mind different possibilities, such as storing the previous value in the bindingContext and have a function which returns the right class, but is it possible to add a custom binding handler which receives the previous value and the new value?
Share Improve this question asked Feb 24, 2013 at 19:34 EdmondoEdmondo 20.1k14 gold badges66 silver badges124 bronze badges 1- Can you describe a bit more the scenario? What does previous mean, on the same row or column? A sample data structure would help too. – Vlad Stirbu Commented Feb 24, 2013 at 20:23
3 Answers
Reset to default 4Although Jeff's and Sławomir's answers would work, I found an alternative that doesn't need any change to the view model nor relies on altering the DOM element object.
function subscribeToPreviousValue(observable, fn) {
observable.subscribe(fn, this, 'beforeChange');
}
ko.bindingHandlers['bindingWithPrevValue'] = {
init: function (element, valueAccessor) {
var observable = valueAccessor();
var current = observable();
console.log('initial value is', current);
subscribeToPreviousValue(observable, function (previous) {
console.log('value changed from', previous, 'to', current);
});
}
};
Naturally, that will only work if the bound property is an observable.
I looked into knockout source and I suppose that you can't access previous value inside update method of bindingHandler but you can store it inside element
ko.bindingHandlers['bindingWithPrevValue'] = {
update: function (element, valueAccessor) {
var prevValue = $(element).data('prevValue');
var currentValue = valueAccessor();
$(element).data('prevValue', currentValue());
// pare prevValue with currentValue and do what you want
}
};
What you could do is create an extender to extend the observables that you wish to track the previous values of. You could then inspect the previous value to do as you wish.
Just pass in the name of the property that will hold the previous value.
ko.extenders.previousValue = function (target, propertyName) {
var previousValue = ko.observable(null);
target[propertyName] = ko.puted(previousValue);
target.subscribe(function (oldValue) {
previousValue(oldValue);
}, target, 'beforeChange');
return target;
};
Then to use it:
function ViewModel() {
this.value = ko.observable('foo').extend({ previousValue: 'previousValue' });
}
var vm = new ViewModel();
console.log(vm.value()); // 'foo'
console.log(vm.value.previousValue()); // null
vm.value('bar');
console.log(vm.value()); // 'bar'
console.log(vm.value.previousValue()); // 'foo'
In your case, you could probably use something like this:
function TableCell(value) {
this.value = ko.observable(value).extend({ previousValue: 'previousValue' });
this.cssClass = ko.puted(function () {
// I'm assuming numbers
var current = Number(this.value()),
previous = Number(this.value.previousValue());
if (current < previous)
return 'lower';
else if (current > previous)
return 'higher';
}, this);
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745223762a4617366.html
评论列表(0条)