Emberjs:在HTML5音频“结束”事件上触发Emberjs事件

时间:2013-05-01 16:44:42

标签: ember.js

目前,我们在Ember.js应用程序中播放了一个音频元素。

Ember版本:

//RC3, Ember Data revision 12.

我们正试图在当前歌曲结束时加载下一首歌曲。

目前,点击“下一步”按钮时会加载下一首歌曲。 这是如何设置的。

路线:

http://localhost:3000/#/player

路由器映射:

App.Router.map(function() {
  this.resource('songs', function() {
    this.resource('song', { path: ":song_id" });
  });
  // the player's route
  this.route('player');
  // Route that redirects back to player so player can load the new song.  
  this.route('loading-next-song'); 
});

自定义事件

App = Ember.Application.create({
  customEvents: {
    'ended': "ended"
  }
});

观点:

// surrounds "next" button, works.
App.NextSongView = Ember.View.extend({ 
  click: function() {
    this.get('controller').send('setNextSong');
  }
});

// surrounds the player, only the click works.
App.NextSongOnEndedView = Ember.View.extend({ 
  ended: function() {
    console.log("song ended"); // doesn't fire.
  },
  click: function() {
    console.log("tests that other events work"); // fires. 
  }
})

PlayerRoute处理程序 有setNextSong事件

App.PlayerRoute = Ember.Route.extend({
  model: function() {
    //Gets SongsController
    var songsController = this.controllerFor("songs"); 
    // Gets Current Song
    return App.Song.find(songsController.get("currentSong"));
  },
  events: {
    setNextSong: function() { 
      // Fires the "setNextSong" method on the Songs Controller
      this.controllerFor('songs').send('setNextSong'); 
      // redirects to "loading-next-song" route which
      // redirects immediately back to player. (so it can reload)
      this.transitionTo('loading-next-song'); 
    }
  }
});

歌曲控制器: 有setNextSong方法。

App.SongsController = Ember.ArrayController.extend({
  currentSong: 1,
  index: 0,
  setNextSong: function() { // loads the next song.
    var newIndex = (this.get("index") + 1);
    this.set("currentSong", this.objectAt(newIndex).get("id"));
    this.set("index", newIndex);
  }
});

因此点击事件会触发,因此我们可以触发下一首歌曲加载。 但是我们希望当前歌曲结束时自动加载下一首歌曲,而不必点击下一步按钮。

在控制台中,播放器加载后,这有效:

$('audio').on('ended', function() {
  $('button').trigger('click'); //sends 'setNextSong' to the proper controller
});

是否有可能让HTML5音频“已结束”事件触发Ember.js事件? 或者有更好的方法可以在Ember中自动播放下一首歌吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

编辑:只是为了展示小提琴中使用的方法:

App.NextSongOnEndedView = Ember.View.extend({
  // hook in here and subscribe to the ended event
  didInsertElement: function() {
    var self = this;
    var player = this.$('audio')[0];
    player.addEventListener('ended', function(event) {
      console.log("ended song");
      self.get('controller').send('setNextSong');
    });
  },
  //remove listener when removed from DOM to avoid memory leaks
  willDestroyElement: function(){
    var player = this.$('audio')[0];
    player.removeEventListener('ended');
  }
});

我还添加了一个工作小提琴来展示这个概念:http://jsfiddle.net/intuitivepixel/AywvW/18/

在Ember.js中,您可以定义customEvents,请参阅此处(http://emberjs.com/guides/understanding-ember/the-view-layer/#toc_adding-new-events),在Ember.js中创建自定义事件的示例:

申请级别

App = Ember.Application.create({
  customEvents: {
    // player event
    'ended': "myCustomEvent"
  }
});

myCutomEvent是您仍需要创建的方法。

如果您的应用程序没有更多特定路由,

应用程序路由级别仅在ApplicationRoute中挂钩。

App.ApplicationRoute = Ember.Route.extend({
  events: {
    // Note: if nothing stops the event from bubbling it will end up here.
    myCustomEvent: function() {
      this.controllerFor('songs').send('setNextSong');
    }
  }
});

特定路线等级 但是如果你有一个NextSongRoute定义了,那么钩子应该放在那里更方便,例如:

App.NextSongRoute = Ember.Route.extend({
  events: {
    myCustomEvent: function() {
      this.controllerFor('songs').send('setNextSong');
    }
  }
});

希望有所帮助