|
class Dtime.View extends Backbone.View |
|
# Call cleanup before removing completely, |
|
# unbind events from this and all children |
|
leave: -> |
|
@cleanup?() |
|
@unbindFromAll() |
|
@remove() |
|
@_leaveChildren() |
|
@_removeFromParent() |
|
|
|
cleanup: -> |
|
@$el.unbind("click", @debugClick) |
|
|
|
render: -> |
|
@attach() |
|
@el |
|
|
|
debugClick: (e)=> |
|
# Just register interest, pass on event |
|
if e.shiftKey && window.rails_env != "production" |
|
window.debug ?= _([]) |
|
window.debug.push @ |
|
console.log "var debug.last() = ", window.debug.last() |
|
e.preventDefault() |
|
true |
|
else |
|
true |
|
|
|
|
|
attach: -> |
|
@children ||= _([]) |
|
@delegateEvents() |
|
@attachSubviews(@el) |
|
@$el.data('attached_view', @) |
|
@$el.bind("click", @debugClick) unless window.rails_env == 'production' |
|
@ |
|
|
|
setElement: (el)-> |
|
$(el).data('attached_view', @) |
|
super(el) |
|
|
|
constructView: (el, include_el = false)-> |
|
return $(el).data('attached_view') if $(el).data('attached_view')? |
|
data = $(el).data() |
|
key = JSON.stringify(data) |
|
@loadedViews ?= {} |
|
|
|
# Attach if already loaded |
|
if @loadedViews[key]? |
|
val = @loadedViews[key] |
|
$(el).replaceWith(val.el) |
|
return val |
|
name = data.view |
|
data.el = $(el) if include_el |
|
klass = Dtime.Views[name] |
|
if klass |
|
val = new klass(data) |
|
@loadedViews[key] = val |
|
@attachChild(val) |
|
return val |
|
else |
|
throw "Tried to build non-existent class #{name}" |
|
|
|
|
|
attachSubviews: (el)-> |
|
parent = @ |
|
$(el).removeClass('attach_view') |
|
$('.attach_view', el).filter -> |
|
$(@).parents('.attach_view').length < 1 |
|
.each ()-> |
|
view = parent.constructView(@, true) |
|
view.attach() |
|
|
|
|
|
# Attaches a child without rendering |
|
attachChild: (view)-> |
|
view.parent = this |
|
@children ||= _([]) |
|
@children.push(view) |
|
|
|
# Renders a child view and adds it to the list of children - does |
|
# nothing to attach the view to the dom - use renderChildInto if this is |
|
# needed. |
|
renderChild: (view)-> |
|
@attachChild(view) |
|
view.render() |
|
|
|
# Renders a child and replaces a specific element with the new |
|
# view.el |
|
renderChildInto: (view, replace_el)-> |
|
@renderChild(view) |
|
@$(replace_el).replaceWith(view.el) |
|
|
|
appendChild: (view, replace_el)-> |
|
@renderChild(view) |
|
@$el.append(view.el) |
|
|
|
# Calls leave on all subviews |
|
_leaveChildren: -> |
|
@children?.chain().clone().each (view)-> |
|
view.leave?() |
|
|
|
# Alerts parent that this view is leaving, |
|
# so that it can be removed from children list |
|
_removeFromParent: ()-> |
|
@parent?._removeChild(this) |
|
|
|
# Removes child from list of children |
|
# called when a child does a "leave" event. |
|
_removeChild: (view)-> |
|
index = @children.indexOf(view) |
|
@children.splice(index, 1) |