0

I've got a copule of files that I'm working with and I'm trying to create a listener on this method I have in my backbone view

appView.js.coffee

namespace "happiness_kpi", (exports) ->
  exports.appView = Backbone.View.extend

    events: 
      "click #happy" : "selection"

    selection: ->
      console.log "selection was called"

index.html.haml

%input{ :type => "image", :src => "/assets/smiley.jpg", :alt => "happy", :id => "happy" }
%input{ :type => "image", :src => "/assets/undecided.jpg", :alt => "undecided", :id => "undecided" }
%input{ :type => "image", :src => "/assets/sad.jpg", :alt => "sad", :id => "sad" }

and here is my spec:
app_view_spec.js.coffee

it "is called when one of the faces is clicked", ->
  $("body").append('<input alt="happy" id="happy" src="/assets/smiley.jpg" type="image">')
  $("body").append('<input alt="undecided" id="undecided" src="/assets/undecided.jpg" type="image">')
  $("body").append('<input alt="sad" id="sad" src="/assets/sad.jpg" type="image">')
  @subject.selection = sinon.spy()

  $("#happy").click

  sinon.assert.calledOnce(@subject.selection)

I'm getting the error 'Error: expected spy to be called once but was called 0 times' Anyone have any ideas as to why the event is not being triggered when the input is clicked?

Thanks in advance.

4

2 回答 2

1

If the problem is not the obvious typo of the brackets when calling click() then the other thing I'm thinking is that the events in Backbone are scoped within the View element. That means that a View cannot list to events happening outside itself (it can, of course, but not by simply using the events object).

Try doing this at the beginning of your test:

@subject.setElement($("body"));

This will set the View el and $el to the body tag, so the images you are appending are actually going inside your View and the events will be triggered.

于 2013-07-16T15:36:13.147 回答
0

So after much research and tinkering, I seem to have come to an answer. The problem was definitely the way that I was appending the images to the iframe. Problem was that the test seemed to be creating a new element outside of the iframe, and was not visible to the page. The $('#happy').click() was executing correctly, however, it was executing on something that didn't exist in the iframe.

So my solution:

app_view_spec.js.coffee

beforeEach ->
  $("body").append('<div id="display"></div>')

afterEach ->
  $("body").append('<div id ="display"></div>').remove()

it "is called when one of the faces is clicked", ->
  @subject.emotionSelection = sinon.spy()
  @subject.delegateEvents()

  $("input#happy").click()

  sinon.assert.calledOnce @subject.emotionSelection

appView.js.coffee el: '#display'

initialize: ->
  @render()

events: ->
  'click #happy': @emotionSelection

render: ->
  @$el.html HandlebarsTemplates.faces()

emotionSelection: ->
  console.log "hello"

I found doing it this way was a much nicer approach, I just appended my HAML to the iframe, rather than trying to append each image on its own. Lesson learned. Thanks for the help!

于 2013-07-17T19:01:14.863 回答