Skip to content

Access computed properties without injecting to the cache #134

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

Closed
Patrik-Lundqvist opened this issue Aug 24, 2014 · 3 comments
Closed

Access computed properties without injecting to the cache #134

Patrik-Lundqvist opened this issue Aug 24, 2014 · 3 comments
Labels

Comments

@Patrik-Lundqvist
Copy link

It would be nice if the computed properties worked with items which have not yet been inserted in to the cache. Example:

var User = DS.defineResource({
  name: 'user',
  computed: {
    fullName: ['first', 'last', function (first, last) {
      return first + ' ' + last;
    }],
  }
});

var newUser = User.createInstance({first:'John', last:'Doe'});

newUser.fullName // Should return 'John Doe'
@jmdobry
Copy link
Member

jmdobry commented Aug 24, 2014

Unfortunately, the way dirty checking works cannot support this. With angular's $scope, dirty-checking does not start until a value is added to the scope. Likewise, dirty-checking does not start until items are injected. In order to setup dirty-checking, observers have to be activated. In order to complete the solution the observers have to be cleaned up when items are ejected. That's the part that is impossible for non-injected items, and this is why I can't implement dirty-checking for non-injected items. Computed properties rely on dirty-checking, so computed properties cannot automatically work for non-injected items. You can however, compute the properties yourself:

function compute (resource, instance) {
  DS.utils.forOwn(resource.computed, function (fn, field) {
    var args = [];
    angular.forEach(fn.deps, function (dep) {
      args.push(instance[dep]);
    });
    // compute property
    instance[field] = fn[fn.length - 1].apply(instance, args);
  });
}

var User = defineResource({
  name: 'name',
  computed: {
    fullName: ['first', 'last', function (first, last) {
      return first + ' ' + last;
    }
  }
});

var user = User.createInstance({ first: 'John', last: 'Doe' });

compute(User, user);

user.fullName; // "John Doe"

It's possible I could add that compute method to the prototype of resource instances, so you could manually re-compute properties, but it would be unavailable if devs use useClass: false.

@Patrik-Lundqvist
Copy link
Author

Oh I see, thanks for the explanation! A compute method to invoke seems like a good solution to me.

@jmdobry
Copy link
Member

jmdobry commented Aug 24, 2014

Closing in favor of #136

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

No branches or pull requests

2 participants