David Miani
David Miani

Reputation: 14668

Making a computed property dependent on all the properties of another object in emberjs

Is it possible to make a property dependent on all the properties of another object? For example: (also in jsfiddle):

html:

<script type="text/x-handlebars" >
    {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="index">
    <p>Weapon damage: {{ input value=model.activeWeapon.damage}} </p>
    <p>Hero damage: {{ model.weaponDamagePerSecond }}</p>
</script>

javascript:

App = Ember.Application.create({});

App.Weapon = Ember.Object.extend({
    damage: null,
    speed: null
});

App.Hero = Ember.Object.extend({
    activeWeapon: null,
    strength: null,
    weaponDamagePerSecond: function() {
      var weapon = this.get('activeWeapon');
      console.log('weapon damage:' + weapon.get('damage'));
      console.log('weapon speed:' + weapon.get('speed'));
      console.log('strength:' + this.get('strength'));
      console.log (weapon.get('damage') + this.get('strength')) * weapon.get('speed');

      return (1.0 * weapon.get('damage') + 1.0 * this.get('strength')) * weapon.get('speed');
    }.property('activeWeapon', 'strength')
    //}.property('activeWeapon.damage', 'activeWeapon.speed', 'strength')
    // the above line will make the example work, but it is a bit painful to 
    // have to specify all the attributes needed of activeWeapon.
});

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return App.Hero.create({
            activeWeapon: App.Weapon.create({
                damage: 40,
                speed: 2
            }),
            strength: 8
        });
    }
});

Is it possible to get weaponDamagePerSecond to update when any property on activeWeapon updates, with having to specify all the properties manually (like in the commented out code)?

Upvotes: 2

Views: 399

Answers (1)

Kingpin2k
Kingpin2k

Reputation: 47367

No, but it's really easy to write up an observer that watches everything and triggers your computed property to update anytime it updates. I'm not necessarily recommending this, but it can be done.

http://jsfiddle.net/5gS59/

App.Weapon = Ember.Object.extend({
    damage: null,
    speed: null,
    version: 0,
    watchingEverything: function(){
        console.log('hello');
        this.incrementProperty('version');
    }.observes('damage','speed')
});


weaponDamagePerSecond: function() {
  var weapon = this.get('activeWeapon');
  console.log('weapon damage:' + weapon.get('damage'));
  console.log('weapon speed:' + weapon.get('speed'));
  console.log('strength:' + this.get('strength'));
  console.log (weapon.get('damage') + this.get('strength')) * weapon.get('speed');

  return (1.0 * weapon.get('damage') + 1.0 * this.get('strength')) * weapon.get('speed');
}.property('activeWeapon.version', 'strength')

You can alternately do a similar thing with just a property and not an observes:

http://jsfiddle.net/XsuxA/1/

Upvotes: 1

Related Questions