Как мне привязать к оконной функции в Ember View?
У меня есть mixin, который автоматически пересчитывает и устанавливает высоту div на размер страницы.
Это работает, но мне кажется глупым быть привязкой к событию jQuery и запускать событие Ember вручную каждый раз, когда он вызывается.
Есть ли способ привязки к событиям окна непосредственно в Ember?
У меня есть упрощенный JSFiddle здесь
Это код:
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)
Ответы
Ответ 1
Нет ничего плохого в регистрации вашего собственного обработчика событий с помощью jQuery для чего-то вроде этого.
У Ember нет обработки событий окна в настоящее время.
Я также предлагаю попытаться найти решение, которое не полагалось бы на глобальные переменные.
Ответ 2
Я знаю, что я опаздываю на несколько лет, но я искал решение той же проблемы и нашел это:
jQuery(window).on('resize', Ember.run.bind(this, this.handleResize));
(источник: Ember.js oficial)
**** P.S.
О реализации этого небольшого трюка - я не знаю, можно ли использовать его в методе контроллера и запускать init (как прокомментировал denis.peplin), я фактически привязываю событие к функции routeController. Я не знаю, лучше ли это, но это работает как прелесть в моем приложении.
Ответ 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')
});
Ответ 4
Я не думаю, что это возможно с помощью Ember.js - единственное место, где он обеспечивает встроенную обработку событий DOM, это для Ember.View(щелчок и т.д.) и, возможно, в других классах, связанных с представлением.
Мы также использовали аналогичные подходы к вашему решению для обработки особых случаев, подобных этому!
Ответ 5
Для тех, кто ищет новые ответы или просто избавится от jquery...
В моем случае я просто хочу узнать, изменилось ли окно до ширины элемента calc.
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));
}
});
И этот слушатель будет жить до тех пор, пока этот компонент не будет жить!