knockout-es5
knockout-es5 copied to clipboard
TypeScript support
Hi,
Let's consider following code:
HTML
<body>
<div data-bind="text: name"></div>
<div data-bind="text: weight"></div>
<div data-bind="text: price"></div>
<div data-bind="text: size"></div>
<button data-bind="click: function() { i.price = 556677; i.name = 'abccccc'; }">Change</button>
<script>
var i = new Module.Item();
i.name = "abc";
i.weight = 34;
i.price = 777;
i.size = 123;
ko.applyBindings(i);
</script>
</body>
TypeScript
module Module {
export class Item {
name: string;
weight: number;
private _price: number;
get price(): number {
return this._price;
}
set price(value: number) {
this._price = value;
}
private _size: number;
get size(): number {
return this._size;
}
constructor() {
this.name = "x";
this.weight = 2233;
ko.track(this, ["name", "price", "size"]);
}
}
}
The problem is that ko-es5 uses only instance members. I've prepared tweak to ko-es5 code, that handles that.
Consider following tweak to ko-es5
propertyNames.forEach(function(propertyName) {
// Skip properties that are already tracked
if (propertyName in allObservablesForObject) {
return;
}
var workOnObj = obj;
var descriptor = Object.getOwnPropertyDescriptor(workOnObj, propertyName);
if (descriptor === undefined) {
workOnObj = Object.getPrototypeOf(obj);
descriptor = Object.getOwnPropertyDescriptor(workOnObj, propertyName);
}
// Skip properties where descriptor can't be redefined
if (undefined === descriptor || false === descriptor.configurable) {
return;
}
var origValue = workOnObj[propertyName],
isArray = Array.isArray(origValue),
observable = ko.isObservable(origValue) ? origValue
: isArray ? ko.observableArray(origValue)
: ko.observable(origValue);
Object.defineProperty(workOnObj, propertyName, {
configurable: true,
enumerable: true,
get: observable,
set: ko.isWriteableObservable(observable) ? observable : undefined
});
allObservablesForObject[propertyName] = observable;
if (isArray) {
notifyWhenPresentOrFutureArrayValuesMutate(ko, observable);
}
});
I'll investigate further compatibility with TS. Having core/pure KO that targets at least ES5/modern browsers with stripped legacy code would be nice.
Note - this isn't specific to TypeScript. As you mentioned the plugin only grabs the instances own properties. I think what you really want to do is track the private properties, since those should be on the instance.
For typescript support check out this decorators that works similar like this plugin.