【问题标题】:How should I bind to a window function in an Ember View?我应该如何绑定到 Ember 视图中的窗口函数?
【发布时间】:2012-06-01 01:31:54
【问题描述】:

我有一个 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')
)

还有调用它的 mixin。

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)

【问题讨论】:

  • 如果您在注册事件处理程序时使用了粗箭头 (=>),则不需要 object = this

标签: ember.js


【解决方案1】:

我知道我迟到了几年,但我一直在寻找解决同一问题的方法,结果发现:

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

(来源:Ember.js ofiicial

**** 关于这个小技巧的实现——我不知道是否可以在控制器方法中使用它并在 init 上触发(正如 denis.peplin 评论的那样),我实际上是在路由的“setupController”函数中绑定事件。我不知道这是否是最佳实践,但它在我的应用中就像一个魅力。

【讨论】:

  • 是的,绑定后如何解绑...?
【解决方案2】:

使用 jQuery 注册自己的事件处理程序并没有什么问题。

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • denis.peplin:函数 bindResizeEvent 在初始化时被调用,但是当我更改 Chrome 浏览器的大小时,该函数不会再次运行。 bindResizeEvent 的预期行为是每次调整浏览器窗口大小时都会运行(这就是我要找的)?
    • 是的,绑定后如何解绑...?
    【解决方案4】:

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

    我们还对您的解决方案使用了类似的方法来处理此类特殊情况!

    【讨论】:

      【解决方案5】:

      对于那些搜索最新答案或只是摆脱 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));
        }
      });
      

      这将监听器将一直存在到该组件存在为止!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-15
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多