sproutcore/sproutcore — pull request #1130 by nicolasbadia (2013-11-25 08:32:34+00:00)
Title: Adds an aggregatePropertyChanges flag to SC.RecordAttribute

Here is a proposal to solve a problem with computed properties depending on the property of a relationship. Here is an example :

MyApp.Foo = SC.Record.extend({

bar: SC.Record.toOne("MyApp.Bar", { inverse: "foo" }),

barBaz: function() {
return this.getPath('bar.baz');
}.property('bar').cacheable(),

});

Currently `barBaz` will not be updated if the `baz` property of `bar`changes. After a long talk with maurits, we couldn't found a clean way to have `barBaz` updated. In fact, we can't use `property('bar.baz').cacheable()` because this is not supported and throw an error like this: `Uncaught Error: Developer Error: The record of type, GX.Invoice, with storeKey, 1029, was materialized a second time before the first call had finished. This will result in two separate instances of the same object being created and should be fixed. A likely cause is using '.observes' code in the record class, which can cause the record to be retrieved somehow while it is still being created.`
Another solution could be to make `barBaz` not cacheable, but it is needed if we want to display it in a list view. The last solution were to had observers manually, which is kind of hacky and not efficient.

So the solution we found here were to create a new property `aggregatePropertyChanges` (I think the name could be review), which, when set to true, will notify the relationship that a property has changed. In the example above, `aggregatePropertyChanges` should be had like this :

MyApp.Bar = SC.Record.extend({

foo: SC.Record.toOne("MyApp.Bar", { inverse: "bar", aggregatePropertyChanges: true }),

baz: SC.Record.attr(String),
qux: SC.Record.attr(String),

});

The only drawback here is that if a property other `baz` is changed (like `qux`), the computed properties of the inverse relationship depending on `bar` will all be notified of a change for nothing. But I suppose this can't be avoid until we decide to support `property('bar.baz').cacheable()`.

I hope my explications are clear. I'd like to hear what you think about it. If you like the idea, I will had unit tests.