目前,我们在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中自动播放下一首歌吗?
感谢您的帮助。
答案 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');
}
}
});
希望有所帮助