View resize event


#1

Would it make sense to request a resize event on views? When developing my ember split-view and now while I am developing some components for d3, having a resize event would simplify the code. Along with a resize event, having a binding for the view width and height would also be helpful. What do you think?


#2

Whole-heartedly agree. Having a didResize hook would be very useful.


#3

I’m don’t think something like this really belongs in Ember. Many apps would never need to be notified of window resizing.

But this is how I’ve solved it, could be extracted to an addon:

app/initializers/resize-notification-service.js

export function initialize(container, application) {
  application.inject('route', 'resizeNotificationService', 'service:resize-notification');
  application.inject('component', 'resizeNotificationService', 'service:resize-notification');
}

export default {
  name: 'resize-notification-service',
  initialize: initialize
};

app/services/resize-notification.js

import Ember from 'ember';

export default Ember.Object.extend( Ember.Evented, {
  _oldWindowWidth: null,
  _oldWindowHeight: null,

  _initResizeHandler: function() {
    var self = this;
    Ember.$( window ).on( 'resize', function( /* event */ ) {
      self._triggerResizeListenersLowLatency();
      Ember.run.debounce( self, self._triggerResizeListeners, 100 );
    });
  }.on( 'init' ),

  _triggerResizeListenersLowLatency: function() {
    var self = this;
    var width = window.innerWidth;
    var height = window.innerHeight;
    if ( ( width !== self.get('_oldWindowWidth') ) || ( height !== self.get('_oldWindowHeight') ) ) {
      self.set( '_oldWindowWidth', width );
      self.set( '_oldWindowHeight', height );
      self.trigger( 'windowResizedLowLatency' );
    }
  },

  _triggerResizeListeners: function() {
    var self = this;
    var width = window.innerWidth;
    var height = window.innerHeight;
    if ( ( width !== self.get('_oldWindowWidth') ) || ( height !== self.get('_oldWindowHeight') ) ) {
      self.set( '_oldWindowWidth', width );
      self.set( '_oldWindowHeight', height );
      self.trigger( 'windowResized' );
    }
  }

});

And then in e.g. your component:

didInsertElement: function() {
  this.resizeNotificationService.on( 'windowResizedLowLatency',
    this, myResizeFunction );
},
willDestroyElement: function() {
  this.resizeNotificationService.off( 'windowResizedLowLatency',
    this, myResizeFunction );
},

#4

There is now an ember-resize add-on.