我有一个ember项目,该项目具有一项服务,该服务根据元素的宽度获取元素的正确字体大小。用于响应式缩放。
这是我的代码。
元素:
screenSizeService: service('screen-size'),
utilsService: service('utils'),
portrait: computed.readOnly('screenSizeService.portrait'),
landscape: computed.readOnly('screenSizeService.landscape'),
style: computed('screenSizeService.{width,height}', 'landscape', 'portrait', function()
{
console.log('calculating');
//Since the properties have to be consumed, get their values
this.get('screenSizeService.width');
this.get('screenSizeService.height');
//Params = scale if it's landscape, scale if it's portrait, min font size, max and the parent to watch the width of
return this.getFontSize(1.2, 1.2, 30, 60, this.$();
}),
getFontSize(landscapeScale, portraitScale, min, max, parent)
{
const scale = (this.get('landscape')) ? landscapeScale : portraitScale;
const fontSize = this.get('utilsService').scaleFontSize(parent, scale, min, max);
return htmlSafe('font-size: ' + fontSize + 'px');
}
因此,它侦听resize事件并在每次更改时进行计算。除了最初加载时,这确实非常有效。
在初次加载时,即时通讯通过的父级没有宽度,因此在调整页面大小之前无法计算其字体大小。
这是我的屏幕尺寸服务:
init()
{
this._super(...arguments);
this.get('resizeService').on('resize', this, this.screenSizeChange);
this.screenSizeChange();
},
willDestroyElement()
{
this._super(...arguments);
this.get('resizeService').off('resize', this, this.screenSizeChange);
},
screenSizeChange()
{
const width = window.innerWidth;
const height = window.innerHeight;
this.set('width', width);
this.set('height', height);
if (width >= height && !this.get('landscape'))
{
this.set('landscape', true);
this.set('portrait', false);
}
if (height > width && !this.get('portrait'))
{
this.set('landscape', false);
this.set('portrait', true);
}
}
最后,我的utils函数计算字体大小:
scaleFontSize(parent, scale, min, max)
{
const parentWidth = (parent && parent.width()) ? parent.width() : null;
if (!parentWidth) {return;}
scale = scale || 1;
min = min || 1;
max = max || 1000;
return Math.max(Math.min(parentWidth / (scale * 10), parseFloat(max)), parseFloat(min));
}
有人会知道一种可能的解决方法,以便它根据didInsertElement进行计算吗?
我尝试在didInsertElement上设置样式,但是在调整大小时它不会改变。我想是因为我将它设置了两次。
需要任何帮助
答案 0 :(得分:1)
我建议使用组件而不是服务,并将您的内容包装在该组件中。这样,您将可以使用didInsertElement
挂钩。
根据您的代码,类似这样的东西:
import Component from '@ember/component';
import $ from 'jquery';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
export default Component.extend({
utilsService: service('utils'),
style: computed('landscape', 'portrait', function() {
return this.getFontSize(1.2, 1.2, 30, 60, this.$();
}),
getFontSize(landscapeScale, portraitScale, min, max, parent) {
const scale = this.get('landscape') ? landscapeScale : portraitScale;
const fontSize = this
.get('utilsService')
.scaleFontSize(parent, scale, min, max);
return htmlSafe('font-size: ' + fontSize + 'px');
},
didInsertElement() {
this._super(...arguments);
//Element inserted, do calculations
this.screenSizeChange();
//Add resize handler
$(window).on('resize', this._resizeHandler);
},
willDestroyElement() {
this._super(...arguments);
//It's important to remove resize handler on destroy, to avoid possible issues
$(window).off('resize', this._resizeHandler);
},
_resizeHandler: computed(function() {
const that = this;
return function() {
that.screenSizeChange();
};
}),
screenSizeChange() {
const width = window.innerWidth;
const height = window.innerHeight;
this.set('landscape', width >= height);
this.set('portrait', width < height);
}
});
顺便说一句,如果它仅包含静态方法(简单函数),则不需要utils
服务。您可以在utils
下创建app
目录并在其中存储实用程序功能,并在代码中进行import scaleFontSize from 'project-name/utils/scale-font-size'
;