Sorted Collections - SortedArrayController in Ember.js
Problem
Need a collection of objects that always render in a sorted order and not the insert order. For example showing events ordered on timestamp.
Update: added maximum size so it will always trim the collection to a running set of n latest items.
Solution
I created this small extension to ember that will keep the collection always sorted (based on a sortFunction or default sort order). It also supports reverse order and random order. The code is in coffeescript but you can convert it to javascript via this tool.
Ember.SortedArrayController = Ember.ArrayController.extend(
sortOrder: "normal"
sortFunction: null
inputCollectionName: "content"
outputCollectionName: "content"
maxCollectionSize: -1
init: ->
@set(@inputCollectionName, [])
@addObserver(@inputCollectionName + '.@each', -> @elementAdded())
@addObserver(@outputCollectionName + '.@each', -> @trimArray())
elementAdded: (->
context = @
content = @get(@inputCollectionName)
if @sortOrder == "normal"
if @sortFunction? then content.sort((a,b)-> context.sortFunction(a,b)) else content.sort()
else if @sortOrder == "reverse"
if @sortFunction? then content.sort((a,b)-> context.sortFunction(b,a)) else content.reverse()
else if @sortOrder == "random"
content.sort((a,b)-> 0.5 - Math.random("deadbeef"))
@set(@outputCollectionName, content)
)
trimArray: (->
content = @get(@outputCollectionName)
@set(@outputCollectionName, content.slice(0, @maxCollectionSize-1))if (@maxCollectionSize > 0) and (content.length > @maxCollectionSize)
)
)
window.myArray = Ember.SortedArrayController.create()
myArray.content.pushObjects(["Jack", "Cassandra", "Raj"])
window.myArray2 = Ember.SortedArrayController.create({sortOrder: "reverse"})
myArray2.content.pushObjects(["Jack", "Cassandra", "Raj"])
window.myArray3 = Ember.SortedArrayController.create({sortOrder: "random"})
myArray3.content.pushObjects(["Jack", "Cassandra", "Raj"])
you will get the following results:
myArray.content
["Cassandra", "Jack", "Raj"]
myArray2.content
["Raj", "Cassandra", "Jack"]
myArray3.content
["Jack", "Raj", "Cassandra"]
Written by Bashir Eghbali
Related protips
1 Response
I made a gist out of the js / non-coffeescript version: https://gist.github.com/chrisjlee/31d1ea4f7cd90517b2d8
over 1 year ago
·
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Ember.js
Authors
ryrych
11.69K
michalbryxi
6.707K
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#