我有一个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事件,并在每次更改时进行计算。这真的很好用,除了它最初加载的时候。
在初始加载时,im所经过的父对象没有宽度,因此在调整页面大小之前无法计算其字体大小。
这是我的屏幕大小服务:
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上设置样式,但它在调整大小时不会改变。我想是因为我设置了两次。
任何帮助都是有价值的
发布于 2019-05-13 04:21:59
我建议使用组件而不是服务,并将内容包装在该组件中。通过这种方式,您将能够使用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服务只包含静态方法(简单函数),则不需要它。您可以在app下创建utils目录,并在其中存储实用程序函数,并在代码中执行import scaleFontSize from 'project-name/utils/scale-font-size';
https://stackoverflow.com/questions/56098575
复制相似问题