我应该如何绑定到Ember View中的窗口函数?

时间:2012-06-01 01:31:54

标签: ember.js

我有一个mixin,可以自动重新计算并设置页面调整大小的div高度。

它有效,但是对我来说,绑定到jQuery事件并在每次调用它时手动触发Ember事件似乎很愚蠢。

有没有办法直接在Ember中绑定窗口事件?

我有一个简化的JSFiddle here

这是代码:

App.windowWrapper = Ember.Object.create(Ember.Evented,
  resizeTimer: null
  init: ->
    @_super()
    object = this
    $(window).on 'resize', ->
      window.clearTimeout(object.resizeTimer)
      object.resizeTimer = setTimeout( App.windowWrapper.resize, 100)
      true

  resize: ->
    App.windowWrapper.fire('resize')
)

正在调用它的混音。

App.Scrollable = Ember.Mixin.create
  classNames: "scrollable"
  init: ->
    Ember.assert("Scrollable must be mixed in to a View", this instanceof Ember.View)
    @_super()

  didInsertElement: ->
    @_super()
    @calculateHeight()
    App.windowWrapper.on('resize', this, 'calculateHeight')

  willDestroyElement: ->
    App.windowWrapper.off('resize', this, 'calculateHeight')
    @_super()

  calculateHeight: ->
    offset       = @$().offset().top
    windowHeight = $(window).height()
    @$().css('height', windowHeight - offset)

5 个答案:

答案 0 :(得分:13)

我知道我已经晚了几年了,但我一直在寻找解决同样问题的方法,并发现了这个问题:

jQuery(window).on('resize', Ember.run.bind(this, this.handleResize));

(来源:Ember.js ofiicial

**** P.S. 关于这个小技巧的实现 - 我不知道是否可以在控制器方法中使用它并在init上触发(如denis.peplin评论),我实际上绑定了事件在路线的setupController'功能。我不知道它是否是最好的练习,但它在我的应用程序中就像一个魅力。

答案 1 :(得分:7)

使用jQuery注册自己的事件处理程序没有任何问题。

Ember目前没有任何窗口事件处理。

我还建议尝试提出一种不依赖于全局变量的解决方案。

答案 2 :(得分:2)

Itay Hamashmid回答的示例代码:

App.ApplicationController = Ember.Controller.extend({
  handleResize: function() {
    console.log('resized');
  },
  bindResizeEvent: function() {
    jQuery(window).on('resize', Ember.run.bind(this, this.handleResize));
  }.on('init')
});

答案 3 :(得分:0)

我认为Ember.js不可能 - 它提供内置DOM事件处理的唯一地方是Ember.View(点击等),也许在其他视图相关的类中。

我们也使用类似的解决方案来处理这类特殊情况!

答案 4 :(得分:0)

对于那些通过最新答案进行搜索或者只是摆脱了jquery的人...

就我而言,我只想知道窗口是否已调整大小以计算元素的宽度。

import Component from '@ember/component';

export default Component.extend({
  size: window.innerWidth,

  init() {
    this._super(...arguments);

    window.addEventListener('resize', ()=> this.set('size', window.innerWidth));
  }
});

是的,我知道没有办法解除这种匿名函数的绑定,但是我已经搜索了,找不到合适的答案...

我想将其重构为使用jquery,但限制范围如下:

import Component from '@ember/component';
import $ from 'jquery';

export default Component.extend({
  size: window.innerWidth,

  init() {
    this._super(...arguments);

    $(document.querySelector('#something'))
              .on('resize', (e)=> this.set('size', e.target.innerWidth));
  }
});

这个侦听器将一直存在,直到该组件存在为止!