主干网在触发n次事件后停止侦听事件



我正在使用非官方的mpdjs库和backbone.js为mpd音乐守护进程编写一个浏览器内远程。collectionView图书馆。数据通过websockets在浏览器和服务器之间传输。

下面的代码块控制事件触发:

App.Views.PlayerView = Backbone.View.extend
  template: _.template(JST.player())
  events:
    'click .song': 'changeSong'
  changeSong: (e) ->
    classList = e.currentTarget.classList
    classList.remove('song')
    classList.remove('ui-sortable-handle')
    songId = classList[0]
    socket.send("play-song:#{songId.split('-')[1]}")
  render: () ->
    emp = @model.toJSON()
    html = @template(emp)
    html = $(html).addClass("song song-#{emp.id}")[0]
    @$el.append(html)
App.Views.PlaylistView = new Backbone.CollectionView
  el: $('.queue')
  selectable: true
  collection: App.CurrentPlaylist
  modelView: App.Views.PlayerView

这些是相关的模型和集合:

App.Models.Song = Backbone.Model.extend
  defaults:
    track: ''
    title: ''
    artist: ''
    album: ''
    length: ''
App.Collections.Playlist = Backbone.Collection.extend
  model: App.Models.Song
App.CurrentPlaylist = new App.Collections.Playlist

当应用启动并连接到WebSocketServer时,以下代码填充以下标记:

 // this is wrapped in socket.onmessage, and is only called once
  parseTime = (time) ->
    min = Math.floor(parseInt(time, 10) / 60)
    sec = Math.floor(parseInt(time, 10) % 60)
    if sec < 10
      sec = "0#{sec}"
    "#{min}:#{sec}"
  for key, value of data.playlist
    song = new App.Models.Song(
      id: value.Id
      track: value.Track.split('/')[0]
      title: value.Title
      artist: value.Artist
      album: value.Album
      length: parseTime(value.Time)
    )
    App.CurrentPlaylist.add(song)
  App.Views.PlaylistView.render()
// this is the markup it spits out
<table class="queue pure-table collection-list selectable" tabindex="0">
  <div data-model-cid="c3">
    <tr class="song song-1">
      <td>3</td>
      <td>Reykjavik Blues</td>
      <td>Inf</td>
      <td>The Go Round</td>
      <td>2:06</td>
      </tr>
  </div>
  <div data-model-cid="c4">
    <tr class="song song-2">
      <td>5</td>
      <td>Wasting Time</td>
      <td>Inf</td>
      <td>The Go Round</td>
      <td>2:30</td>
    </tr>
  </div>
</table>

当'play-song-2'发送到服务器时,调用以下函数:'2'是从'play-song-2'解析出来的,所以这个函数可以正常工作。

function playSong(ws, songId) {
  mpdConnection.sendCommand('playid ' + songId, function(err, msg) {
    if (err) throw err;
    // this is a helper function that takes the plain text response
    // and organizes it into a javascript object
    msg = msgToObject(msg);  
    msg.type = 'song-update';
    ws.send(JSON.stringify(msg));
  });
}

我所面临的问题是,然而,当页面加载时,changeSong(e)在点击.song后几乎立即被触发。但是,如果页面上有n首歌曲,则单击n次后页面将停止侦听事件。

更新:我似乎意外地修复了这个问题与一些布局的变化。我修改了视图,以便在渲染时插入一个tr而不是插入一个div:

App.Views.PlayerView = Backbone.View.extend
  tagName: 'tr'
  template: _.template(JST.player())
  events:
    'click': 'changeSong'

和我拿走了.song类选择器,选择在所有点击时侦听事件。有了选择器,原始的、破碎的行为仍然存在,但没有选择器,玩家就能很好地工作。然而,我仍然不确定为什么这真的有效,所以我悬赏任何能解释这一点的人。

这是你的视图

App.Views.PlayerView = Backbone.View.extend
  events:
    'click .song': 'changeSong'
  changeSong: (e) ->
    classList = e.currentTarget.classList
    classList.remove('song')
    # your logic

现在根据您的events散列,它表示每当单击类名称为song的元素时,然后执行方法changeSong。但是在changeSong内部,您正在删除类名song。因此,事件处理程序只运行一次!因为一旦它运行,类名song就被删除了。

如果你有4首歌,一次点击其中的4首&然后在没有点击之后将触发changeSong方法。

相关内容

  • 没有找到相关文章

最新更新