174 lines
4.7 KiB
CoffeeScript
174 lines
4.7 KiB
CoffeeScript
#
|
|
# Crafting Guide - base_controller.coffee
|
|
#
|
|
# Copyright © 2014-2017 by Redwood Labs
|
|
# All rights reserved.
|
|
#
|
|
|
|
{Observable} = require("crafting-guide-common").util
|
|
templates = require './templates'
|
|
|
|
########################################################################################################################
|
|
|
|
module.exports = class BaseController extends Backbone.View
|
|
|
|
constructor: (options={})->
|
|
@_children = []
|
|
@_model = null
|
|
@_parent = options.parent
|
|
@_rendered = false
|
|
|
|
@router = options.router
|
|
|
|
@tryRefresh = _.debounce (=> @_tryRefresh()), 100
|
|
|
|
@_loadTemplate options.templateName
|
|
super options
|
|
|
|
# Public Methods ###############################################################################
|
|
|
|
addChild: (Controller, atSelector, options={})->
|
|
if not _.isFunction Controller then throw new Error "Controller must be a constructor"
|
|
|
|
options.el = @$(atSelector)[0]
|
|
options.parent = this
|
|
|
|
child = new Controller options
|
|
child.render options
|
|
@_children.push child
|
|
return child
|
|
|
|
hide: ($el)->
|
|
$el ?= @$el
|
|
$el.css 'display', 'none'
|
|
|
|
refresh: ->
|
|
logger.verbose => "#{this} refreshing"
|
|
|
|
remove: ->
|
|
@$el.remove()
|
|
@off()
|
|
|
|
routeLinkClick: (event)->
|
|
$link = $(event.target)
|
|
if not $link.attr('href')?
|
|
$link = $(event.currentTarget)
|
|
|
|
href = $link.attr 'href'
|
|
target = $link.attr 'target'
|
|
|
|
logger.info -> "Re-routing link to internal navigation: #{href}"
|
|
|
|
if href? and href.match /^http/
|
|
tracker.trackEvent c.tracking.category.navigate, 'external-link', href
|
|
.then -> window.location.href = href
|
|
return false
|
|
else if target?
|
|
tracker.trackEvent c.tracking.category.navigate, 'external-link', href
|
|
return true
|
|
else
|
|
tracker.trackEvent c.tracking.category.navigate, 'internal-link', href
|
|
@router.navigate href, trigger:true
|
|
return false
|
|
|
|
show: ($el)->
|
|
$el ?= @$el
|
|
$el.css 'display', ''
|
|
|
|
unrender: ->
|
|
@undelegateEvents()
|
|
@$el.empty()
|
|
@_rendered = false
|
|
|
|
# Event Methods ################################################################################
|
|
|
|
onDidModelChange: ->
|
|
@tryRefresh()
|
|
|
|
onWillRender: -> # do nothing
|
|
|
|
onDidRender: -> # do nothing
|
|
|
|
onWillShow: -> # do nothing
|
|
|
|
onDidShow: -> # do nothing
|
|
|
|
onWillChangeModel: (oldModel, newModel)->
|
|
if oldModel?.isObservable
|
|
oldModel.off target:this
|
|
|
|
if newModel?.isObservable
|
|
newModel.on Observable::ANY, this, "onDidModelChange"
|
|
|
|
return newModel
|
|
|
|
# Property Methods #############################################################################
|
|
|
|
Object.defineProperties @prototype,
|
|
model:
|
|
get: -> @_model
|
|
set: (newModel)->
|
|
return if @model is newModel
|
|
|
|
newModel = @onWillChangeModel @_model, newModel
|
|
@_model = newModel
|
|
@onDidModelChange()
|
|
|
|
rendered:
|
|
get: -> @_rendered
|
|
|
|
user:
|
|
get: -> @_user
|
|
set: (newUser)->
|
|
@_user = newUser
|
|
@tryRefresh()
|
|
|
|
# Backbone.View Overrides ######################################################################
|
|
|
|
events: ->
|
|
return {}
|
|
|
|
render: (options={})->
|
|
options.force ?= false
|
|
options.show ?= true
|
|
return this unless not @_rendered or options.force
|
|
|
|
if not @_template?
|
|
logger.error => "Default render called for #{@constructor.name} without a template"
|
|
return this
|
|
|
|
data = (@model?.toHash? and @model.toHash()) or @model or {}
|
|
logger.verbose => "#{this} rendering with data: #{data}"
|
|
$renderedEl = $($(@_template(data))[0])
|
|
|
|
@onWillRender()
|
|
@unrender()
|
|
|
|
@$el.append $renderedEl.children()
|
|
@$el.addClass $renderedEl.attr 'class'
|
|
@$el.data $renderedEl.data()
|
|
@delegateEvents()
|
|
|
|
@$el.controller = this
|
|
@_rendered = true
|
|
@onDidRender()
|
|
|
|
@refresh()
|
|
|
|
return this
|
|
|
|
# Object Overrides #############################################################################
|
|
|
|
toString: ->
|
|
return "#{@constructor.name}.#{@cid}"
|
|
|
|
# Private Methods ##############################################################################
|
|
|
|
_loadTemplate: (templateName)->
|
|
if templateName?
|
|
@_template = templates[templateName]
|
|
|
|
_tryRefresh: ->
|
|
return unless @_rendered
|
|
@refresh()
|