Hortitude
Hortitude

Reputation: 14058

ember properties and javascript chaining

Looking at the ember.js documentation (http://emberjs.com/guides/object-model/computed-properties/) I understand how to use properties, but hadn't run across chained methods in an object declaration before.

It looks to me like the property method should get called immediately, but this doesn't seem to be the case.

Person = Ember.Object.extend({
  // these will be supplied by `create`
  firstName: null,
  lastName: null,

  fullName: function() {
    var firstName = this.get('firstName');
    var lastName = this.get('lastName');

   return firstName + ' ' + lastName;
  }.property('firstName', 'lastName')
});

var tom = Person.create({
  firstName: "Tom",
  lastName: "Dale"
});

tom.get('fullName') // "Tom Dale"

If I make a small js snippet, nothing here seems to do anything. http://jsfiddle.net/xXStr/

var a = {
    what: function() {
        alert ("oh yeah");
    },
    bar: function() {
        alert ("bar");
        return this;
    }.what()
}
a.bar();

How do chained methods in an object declaration work?

Upvotes: 2

Views: 404

Answers (1)

ahmacleod
ahmacleod

Reputation: 4310

If you look inside the Ember source, you will find that the Function prototype is extended to include a property method.

Function.prototype.property = function() {
  var ret = Ember.computed(this);
  return ret.property.apply(ret, arguments);
};

Looking deeper, we see that Ember.computed returns an instance of Ember.Computed.

Ember.computed = function(func) {
  var args;

  if (arguments.length > 1) {
    args = a_slice.call(arguments, 0, -1);
    func = a_slice.call(arguments, -1)[0];
  }

  var cp = new ComputedProperty(func);

  if (args) {
    cp.property.apply(cp, args);
  }

  return cp;
};

// ...

function ComputedProperty(func, opts) {
  this.func = func;
  this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true;
  this._dependentKeys = opts && opts.dependentKeys;
}

Ember.ComputedProperty = ComputedProperty;

Thus, whenever you write

foo: function() {
  return this.get('bar')
}.property('bar')

you are actually creating an anonymous function and then immediately invoking its property method, returning an instance of Ember.ComputedProperty. This is what gets assigned to the foo property.

Upvotes: 1

Related Questions