While digging around in the Ember.js API docs, I encountered a mention of a computed property syntax that I hadn’t seen before. Quoth the docs for the computed.empty alias:
Note: When using Ember.computed.empty to watch an array make sure to use the array.[] syntax so the computed can subscribe to transitions from empty to non-empty states.
This sounded intriguing, but wasn’t actually very instructive. A quick ask around the office revealed that no one else had encountered this syntax before either. The quest for knowledge was on.
I spent 15 or 20 minutes grepping through the docs and didn’t find any conclusive reference on this syntax. I’ve always found the Ember.js source code to be extremely well documented in the past, so I decided to focus on locating the source responsible for handling an Ember.get('array.[]')
call. The easiest way to do this, of course, was to set up such a call and just trace the execution.
I pulled up a page of our application that already had an array of data, set a breakpoint at the top level Ember.get()
function, and using the Ember inspector, called a $E.get('foo.[]')
on the page’s controller. From there, it was pretty simple to follow the code execution through to ember-runtime/lib/mixins/array.js
.
Quoth the source code:
/**
This is the handler for the special array content property. If you get
this property, it will return this. If you set this property it a new
array, it will replace the current content.This property overrides the default property defined in `Ember.Enumerable`.
@property []
@return this
*/
‘[]’: Ember.computed(function(key, value) {
if (value !== undefined) this.replace(0, get(this, ‘length’), value) ;
return this ;
}),
So the mystery of the ‘array.[]’ computed property was solved. When you bind an array’s content to the ‘[]’ property, Ember will use a call to replace rather than simple assignment, retaining the array identity and thus properly retaining all the computed properties dependent upon it.
What source code have you gone spelunking into recently? If you, like me, have found something you’ve anticipated to be extraordinarily complex that turns out to be really simple, leave a comment.
Good detective work!
This is now mentioned in the docs here:
https://guides.emberjs.com/v2.4.0/object-model/computed-properties-and-aggregate-data/
“Sometimes you don’t care if properties of individual array items change. In this case use the [] key instead of @each. Computed properties dependent on an array using the [] key will only update if items are added to or removed from the array, or if the array property is set to a different array.”