IdeaBlade/Breeze — pull request #40 by andrew-veresov (2014-03-26 12:39:12+00:00)
Title: Link property back to the entity and property description

This is to allow creating bindings which bound to a property and use entity to which property belongs to and/or property metadata internally.

For example next binding adds isChanged computed to the property and use created computed observable to add/remove 'changed' class to the element:

(function (ko) {

ko.bindingHandlers['breeze'] = {
'after': ['value', 'attr'],
'init': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = valueAccessor();
if (options != undefined) {
if (options.trackChanges != undefined && ko.isObservable(options.trackChanges) && options.trackChanges.parentEntity != undefined) {
var entity = options.trackChanges.parentEntity;
var propName = options.trackChanges.propertyDescriptor.name;

options.trackChanges.isChanged = ko.computed(function () {
return entity.entityAspect.originalValues.hasOwnProperty(propName)
& entity.entityAspect.originalValues[propName] != options.trackChanges();
});

options.trackChanges.isChanged.subscribe(function (isChanged) {
if (isChanged) {
$(element).addClass('changed');
} else {
$(element).removeClass('changed');
}
})
}
//other bindings...
if (options.validate != undefined && ko.isObservable(options.validate) && options.validate.parentEntity != undefined) {
var propertyName = options.validate.propertyDescriptor.name;
ko.bindingHandlers.breezevalidation.init(element, function() { return { properties: [propertyName] }; }, allBindings, viewModel, bindingContext);
}
}
}
};

})(window.ko || require(['ko']));

Using above binding we can enable per property change tracking only for specific properties which need it and avoid spawning isChanged computed for all properties.