3

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

灰烬版本:

//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 中自动播放下一首歌曲?

谢谢您的帮助。

4

1 回答 1

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');
    }
  }
});

特定的 Route 级别 ,但如果你有一个NextSongRoute定义,那么钩子应该更方便地放置在那里,例如:

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

希望能帮助到你

于 2013-05-01T16:48:32.290 回答