How to create an Ember computed property that adds

2019-07-04 01:02发布

问题:

I'm just learning Ember and I'm a bit confused about computed properties. Everything in the guides uses strings, like a computed property that creates a full name out of a first and last name, etc. Anyway, I'm confused about how to use integers because it seems like the syntax almost demands the use of strings.

As an example, I have a property on my controller called count.

import Ember from 'ember';

export default Ember.Controller.extend({
  count: 0,

  counter: Ember.computed('count', function() {
    var num = `${this.get('count')}`;
    var newNum = parseInt(num) + 1;
    this.set('count', newNum);
    return this.get('count');
  })
});

I know this code is really bad, I'm just trying to illustrate what I'm trying to do and failing at. Why does Ember.computed take a string as its first parameter?

And why do I have to use a string in this.get and this.set when I'm working with an integer, not a string? I have to manually parse the int or else it returns a string, why is it converting my count property into a string?

Anyway, in the ember inspector when I run

$E.get('count')

it does successfully add 1, but fails to continue to add 1, which makes me think its not updating the actual count property.

Thanks very much. I appreciate the help.

回答1:

I set up a Ember Twiddle based on your code. I'll try to address each of your questions:

You can think of an Ember.Object as a wrapper around {}. All Ember.Object keys are Strings, because {} keys are strings in Javascript.

For each property stored on an Ember.Object, that property is a value with some String as its key. To look up that value, you have to provide the "path" or "location" of the value, as given by the key (just like a hash table). This is why you need to specify a string in get and set.

Values can be any type in Javascript, not just strings. Take a look at the Ember Twiddle I posted, and open up your console. In your code, num is a string because you've wrapped it in an ES6 template string, which is converting the value of this.get('count').


Ember.computed was designed to render data into templates. It's important to understand that:

  • It's lazy
  • It caches the result of the computation.
  • A Computed Property will only recompute if one or more of the properties it depends on changes.

When you call Ember.computed, you first pass in any number of strings. Each string is a path to a value (on an Ember.Object) that your CP "depends" on.

Because CPs are lazy, 'counter' will only be computed when you access it in your code, or in a template. If 'count' were to change, the cached value of 'counter' would be forgotten. The next time 'counter' were accessed, it would recompute.

In this case, the 'counter' CP function only runs once, because 'count' never changes. This is why you only observe one addition.