Backbone监听器似乎没有被触发

时间:2013-07-16 14:31:06

标签: backbone.js

我有一个我正在使用的文件副本,我正在尝试使用我在骨干视图中的这个方法创建一个监听器

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" }

这是我的规格:
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)

我收到错误'错误:预期间谍被调用一次但被调用0次'任何人都有任何想法为什么在点击输入时没有触发事件?

提前致谢。

2 个答案:

答案 0 :(得分:1)

如果在调用click()时问题不是括号中明显的拼写错误,那么我想到的另一件事是Backbone中的事件是在View元素中确定的。这意味着View无法列出自身外部发生的事件(当然,它可以通过简单地使用events对象来实现)。

在测试开始时尝试这样做:

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

这会将视图el$el设置为正文标记,因此您附加的图片实际上会进入您的视图,并且会触发事件。

答案 1 :(得分:0)

经过大量的研究和修补,我似乎已经得到了答案。问题肯定是我将图像附加到iframe的方式。问题是测试似乎是在iframe之外创建一个新元素,并且页面不可见。 $('#happy').click()正在正确执行,但是,它正在iframe中不存在的内容上执行。

所以我的解决方案:

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:&#39; #display&#39;

initialize: ->
  @render()

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

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

emotionSelection: ->
  console.log "hello"

我发现这样做是一种更好的方法,我只是将我的HAML附加到iframe,而不是试图自己附加每个图像。学过的知识。谢谢你的帮助!