Bind DOM events to view methods based on element attributes.

For example, if you give an element the attribute click: 'elementClicked', the template will bind a click event to that element which calls the elementClicked method on the view.
This commit is contained in:
Nathan Sobo
2011-12-27 19:00:00 -06:00
parent 7948543a5b
commit ba18614c2f
2 changed files with 35 additions and 5 deletions

View File

@@ -14,13 +14,15 @@ fdescribe "Template", ->
list: ->
@ol =>
@li outlet: 'li1', class: 'foo', "one"
@li outlet: 'li2', class: 'bar', "two"
@li outlet: 'li1', click: 'li1Clicked', class: 'foo', "one"
@li outlet: 'li2', keypress:'li2Keypressed', class: 'bar', "two"
viewProperties:
initialize: (attrs) ->
@initializeCalledWith = attrs
foo: "bar"
foo: "bar",
li1Clicked: ->,
li2Keypressed: ->
view = Foo.build(title: "Zebra")
@@ -43,3 +45,16 @@ fdescribe "Template", ->
expect(view.li1).toMatchSelector("li.foo:contains(one)")
expect(view.li2).toMatchSelector("li.bar:contains(two)")
it "binds events for elements with event name attributes", ->
spyOn(view, 'li1Clicked')
spyOn(view, 'li2Keypressed')
view.li1.click()
expect(view.li1Clicked).toHaveBeenCalled()
expect(view.li2Keypressed).not.toHaveBeenCalled()
view.li1Clicked.reset()
view.li2.keypress()
expect(view.li2Keypressed).toHaveBeenCalled()
expect(view.li1Clicked).not.toHaveBeenCalled()

View File

@@ -4,11 +4,15 @@ Builder = require 'template/builder'
module.exports =
class Template
@events: 'blur change click dblclick error focus keydown
keypress keyup load mousedown mousemove mouseout mouseover
mouseup resize scroll select submit unload'.split /\s+/
@buildTagMethod: (name) ->
this.prototype[name] = (args...) -> @builder.tag(name, args...)
_.each(Builder.elements.normal, (name) => @buildTagMethod(name))
_.each(Builder.elements.void, (name) => @buildTagMethod(name))
@buildTagMethod(name) for name in Builder.elements.normal
@buildTagMethod(name) for name in Builder.elements.void
@build: (attributes) ->
(new this).build(attributes)
@@ -18,6 +22,7 @@ class Template
@content(attributes)
view = @builder.toFragment()
@wireOutlets(view)
@bindEvents(view)
if @viewProperties
$.extend(view, @viewProperties)
view.initialize?(attributes)
@@ -28,3 +33,13 @@ class Template
elt = $(this)
outletName = elt.attr('outlet')
view[outletName] = elt
bindEvents: (view) ->
for event in this.constructor.events
view.find("[#{event}]").each ->
elt = $(this)
methodName = elt.attr(event)
elt[event](-> view[methodName]())