Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript support #32

Open
wgebczyk opened this issue Feb 3, 2015 · 2 comments
Open

TypeScript support #32

wgebczyk opened this issue Feb 3, 2015 · 2 comments

Comments

@wgebczyk
Copy link

wgebczyk commented Feb 3, 2015

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.

@jrsearles
Copy link
Contributor

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.

@jmvtrinidad
Copy link
Contributor

For typescript support check out this decorators that works similar like this plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants