Skip to content

Instantly share code, notes, and snippets.

@micahroberson
Last active December 16, 2015 20:29
Show Gist options
  • Save micahroberson/5493159 to your computer and use it in GitHub Desktop.
Save micahroberson/5493159 to your computer and use it in GitHub Desktop.
Backbone Collection extension to maintain hash of models on attributes or user-defined functions
class BaseCollection extends Backbone.Collection
initialize: () ->
@_hash_keys = {}
# @hashOn 'last_name', false
# Start hashing on passed in attribute or method on the model that returns a string
# unique indicates whether or not mulitple models in the collection have the same value for this attribute
# If unique is true, we'll keep track of all models with the same value instead of overwriting in the store
hashOn: (key, unique) ->
if undefined == unique
unique = true
@_hash_keys[key] = unique
@_hashModels key, unique
# Clear hash on the key passed in and stop listening in the future
stopHashing: (key) ->
delete @_hash_keys[key]
delete @["_#{key}_hash"]
@stopListening @, 'add reset'
@each (model) => @stopListening model, "change:#{key}"
# key is the attribute originally set via hash_keys(e.g. 'name'), lookup_val is the search term (e.g. 'Frank')
retrieveFromHash: (key, lookup_val) ->
if !key then return []
# Returns either a single model if attr is unique or an object of models hashed on cid
@["_#{key}_hash"][lookup_val]
_hashModels: (key, unique) ->
@["_#{key}_hash"] = {}
hashSingle = (model) =>
hk = if typeof model[key] == 'function' then model[key]() else model.get(key)
if hk
if !unique
# If first key entry, initialize empty object
if !_.has(@["_#{key}_hash"], hk)
@["_#{key}_hash"][hk] = {}
@["_#{key}_hash"][hk][model.cid] = model
else
@["_#{key}_hash"][hk] = model
@listenTo model, "change:#{key}", (m) =>
nhk = if typeof m[key] == 'function' then m[key]() else m.get(key)
if !unique
# Remove previous key
delete @["_#{key}_hash"][hk][m.cid]
# Rehash on new key
if !_.has(@["_#{key}_hash"], nhk)
@["_#{key}_hash"][nhk] = {}
@["_#{key}_hash"][nhk] = m unless !nhk
else
# Remove previous key
delete @["_#{key}_hash"][hk]
# Rehash on new key
@["_#{key}_hash"][nhk] = m unless !nhk
@listenTo @, 'add', hashSingle
@listenTo @, 'reset', (collection) =>
@["_#{key}_hash"] = {}
_.each(@models, hashSingle, @)
@listenTo @, 'remove', (model) =>
hk = if typeof model[key] == 'function' then model[key]() else model.get(key)
if !unique
delete @["_#{key}_hash"][hk][model.cid]
else
delete @["_#{key}_hash"][hk]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment