Ember如何抓住行动'结束'来自控制器上的html5视频标签?

时间:2015-12-01 20:27:16

标签: javascript ember.js

我有一个带html5视频标记的hbs文件:

<video id="externalVideo" controls loop>
    <source src="../assets/videos/test.mp4" type="video/mp4">
    Your browser does not support HTML5 video.
</video>

我尝试在视频结束时触发操作并在模板的控制器上处理事件,但我似乎无法在控制器上捕获事件,我该怎么办?这样做?

版本:

  • ember-cli:1.13.8
  • ember:2.2.0

2 个答案:

答案 0 :(得分:2)

[编辑:此答案不适用于非冒泡事件,请参阅我的其他答案]

您有三种选择,从最佳到最差:

  1. 使用{{action 'videoEnded' on='ended'}}。这应该会产生一个常规操作,您可以在控制器或路径actions: {}中使用。
  2. ended事件添加到events that Ember will watch automatically列表中:

    customEvents: {
      ended: 'videoEnded'
    }
    

    customEvents必须在创建时传递给应用程序(在您传递rootElement的同一位置)。具体取决于您的确切启动过程,无论您使用的是ember-cli,还是......

    正确配置后,ember将收听ended个事件,并在您的视图或组件上查找名为videoEnded的函数。

  3. 手动事件处理程序(除非您正在创建插件或因某些原因无法使用1.或2.),否则不推荐使用。

    init: function () {
        this._super();
        this._videoEnded = this.videoEnded.bind(this);
    },
    registerEvents: Ember.on('didInsertElement', function () {
        this.get('element').addEventListener('ended', this._videoEnded, false);
    }),
    unregisterEvents: Ember.on('willDestroyElement', function () {
        this.get('element').removeEventListener('ended', this._videoEnded, false);
    }),
    videoEnded: function (evt) { Ember.run(function () {
        console.log('Video ended');
    })}
    

    告诉你它会有点乱。在init中,我们创建了处理程序的绑定版本,以便this在调用时具有正确的值。然后我们在Ember创建DOM元素后注册该事件,并在拆解过程中取消注册它。

    最后,我们将处理程序放在run loop中以确保Ember将检测属性更改并正确运行触发器和绑定。

答案 1 :(得分:0)

我的另一个答案忽略了ended事件没有泡沫的事实。我把它留在身边,因为对于那些在冒泡事件中遇到同样问题的人来说这可能是有用的。

现在,由于事件没有冒泡,您必须手动处理它。有点像我的另一篇文章的选项3)。我强烈建议将其封装到一个组件中:

// video-player/component.js
import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'video',
  attributeBindings: ['autplay', 'buffered', 'controls', 'crossorigin',
                      'loop', 'muted', 'played', 'preload', 'poster', 'src'],

  init: function () {
    this._super();
    this._events = {};
    Object.keys(this.events).forEach(function (name) {
      this._events[name] = function (evt) { Ember.run(this, this.events[name]); };
    }, this);
  }

  registerHandlers: Ember.on('didInsertElement', function () {
    var el = this.get('element');
    Object.keys(this._events).forEach(function (name) {
      el.addEventListener(name, this._events[name], false);
    }, this);
  }),
  unregisterHandlers: Ember.on('willDestroyElement', function () {
    var el = this.get('element');
    Object.keys(this._events).forEach(function (name) {
      el.removeEventListener(name, this._events[name], false);
    }, this);
  }),

  events: {
    play: function (evt) { this.sendAction('play'); },
    ended: function (evt) { this.sendAction('ended'); }
    // add more at will
  }
});

您应该能够像这样使用它:

{{#video-player id="externalVideo" controls loop ended='videoEnded'}}
  <source src="../assets/videos/test.mp4" type="video/mp4">
  Your browser does not support HTML5 video.
{{/video}}