npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ember-classy-computed

v0.0.1

Published

An Ember addon for Class based Computed Properties

Downloads

5

Readme

ember-classy-computed

ember-classy-computed introduce a mechanism for class based computed properties which essentially enables keeping state in computed properties (as opposed to normal computed properties which are stateless).

Keeping that state inside of the computed property instead of in the instance of the class it is defined on enables new kinds of computed property macros that are currently hard to implement:

  • computed property macros can use services without having to inject the service into the class they are defined on
  • computed property macros with dynamic dependent keys
  • computed property macros that depend on external invalidation triggers other than those expressible as dependent keys, e.g. events

Class based computed properties are essentially equivalent to class based helpers.

Use Case

An example use case for a class based computed property is a macro that creates a computed property with dynamic dependent keys that cannot be know upfront.

Defining a computed property that filters a collection property by the value of an attribute of each element is as easy as

filteredUsers: Ember.computed('[email protected]', function() {
  return users.filterBy('isActive')
})

This will filter the users collection by the isActive attribute of each user so that filteredUsers only includes users for which that attribute is true. This computed property depends on each user's isActive property obviously.

What if the property that the users are to be filtered by might change though? In that case you might write sth. like this:

filteredUsers: Ember.computed('filter', function() {
  return users.filterBy(this.get('filter'))
})

This now filter the users by whatever property name is returned by filter. The problem with this is that the filteredUsers property does not depend on any of the individual user's properties anymore so that it would not be recomputed when any of these user's properties change. There is also no way to express the fact that filteredUsers depends on [email protected] when filter is 'isActive' and on [email protected] when filter is 'isAdmin'.

Typicall this case would be solved by defining an observer on the context object's filter property and whenever that changes redefining the filteredUsers computed property with the correct dependent keys for the current value of filter (an alternative solution would be to override the filter property's set method and redefine filteredUsers there).

That would make it impossible to reuse the implementation though (except in a mixin which leads to other problems though). ember-classy-computed' mechanism for class based computed properties makes it possible to reuse that implementation- by providing a context for the computed property itself that the observer etc. can be defined on. This allows something like:

import filterByProperty from 'app/computeds/filter-by';

…

filteredUsers: filterByProperty('users' 'filter')

The logic for the filterByProperty macro is encapsulated in the DynamicFilterByComputed class:

// app/computeds/filter-by.js
import Ember from 'ember';
import ClassBasedComputedProperty from 'ember-classy-computed';

const { observer, computed: { filter }, defineProperty } = Ember;

const DynamicFilterByComputed = ClassBasedComputedProperty.extend({
  filterPropertyDidChange: observer('filterProperty', function() {
    let filterProperty = this.get('filterProperty');
    let property = filter(`collection.@each.${filterProperty}`, (item) => item.get(filterProperty));
    defineProperty(this, 'content', property);

    // This method is provided by the ClassBasedComputedProperty
    // base class and invalidates the computed property so that
    // it will get recomputed on the next access.
    this.invalidate();
  }),

  // This method is called whenever the computed property on the context object
  // is recomputed. The same lazy recomputation behavior as for regular computed
  // properties applies here of course. The method receives the current values
  // of its dependent properties as its arguments.
  compute(collection, filterProperty) {
    this.set('collection', collection);
    this.set('filterProperty', filterProperty);

    return this.get('content');
  }
});

export default ClassBasedComputedProperty.property(DynamicFilterByComputed);

Here the computed property's logic is completely self-contained in the DynamicFilterByComputed class so that it can easily be used via the filterByProperty macro while still ensuring correct dependent keys even when the dynamic filter property changes.

Installation

ember install ember-classy-computed

License

ember-classy-computed is developed by and © simplabs GmbH and contributors. It is released under the MIT License.