[英]lit element event listener doesn't force re render
I have the following code:我有以下代码:
@property({type: Number}) ScreenSizeEnum = ScreenSize.Desktop;
@property({type: Array}) menuData: IMenu[] = [];
@property({type: Boolean}) isMobileMenuOpen: boolean = false;
constructor() {
super();
}
connectedCallback() {
super.connectedCallback();
window.addEventListener('resize', this.onResizeEvent);
}
disconnectedCallback() {
window.removeEventListener('resize', this.onResizeEvent);
super.disconnectedCallback();
}
onResizeEvent() {
let oldVal = this.ScreenSizeEnum;
if (window.outerWidth > 1000) {
this.ScreenSizeEnum = ScreenSize.Desktop;
} else if (window.outerWidth > 700 && window.outerWidth < 1000) {
//Tablet
this.ScreenSizeEnum = ScreenSize.Tablet;
} else if (window.outerWidth < 700) {
// mobile
this.ScreenSizeEnum = ScreenSize.Mobile;
}
}
render() {
let device = this.getDeviceType();
if (device == "desktop" || this.ScreenSizeEnum == ScreenSize.Desktop) {
return html`
<nav class="animate__animated animate__bounce animate__slow">
<ul class="menu-ul">
${this.menuData.map(
menuItem => html`
<universe-menu-main .linkText="${menuItem.linkText}" .link="${menuItem.link}" .subMenu="${menuItem.subMenu}"></universe-menu-main>
`
)}
</ul>
</nav>
`
} else if (device == 'tablet' || this.ScreenSizeEnum == ScreenSize.Tablet) {
return html`
<tablet-menu .menuData="${this.menuData}"></tablet-menu>
`;
} else if (device == 'mobile' || this.ScreenSizeEnum == ScreenSize.Mobile) {
return html`
<mobile-menu .menuData="${this.menuData}" .isOpen="${this.isMobileMenuOpen}"></mobile-menu>
`;
}
}
getDeviceType() {
const ua = navigator.userAgent;
if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
return "tablet";
}
if (
/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(
ua
)
) {
return "mobile";
}
return "desktop";
};
The resize event is fired, however whenever it changes the ScreenSizeEnum
, the render
function does not run.触发 resize 事件,但是每当它更改ScreenSizeEnum
, render
函数都不会运行。
Why does this happen, and how might I fix this?为什么会发生这种情况,我该如何解决?
Your problem is on how you have subscribed to the events and the funky behaviour of this
in JS:您的问题在于您如何订阅事件以及在 JS 中的this
时髦行为:
window.addEventListener('resize', this.onResizeEvent);
This means that inside onResizeEvent()
the term this
will refer to the window being resized, not your component.这意味着在onResizeEvent()
,术语this
将指正在调整大小的窗口,而不是您的组件。
You can fix this by using a lambda to force the this
context (as inside the =>
body this
is always the current context, not the event's:您可以通过使用 lambda 强制this
上下文来解决此问题(在=>
正文中, this
始终是当前上下文,而不是事件的:
window.addEventListener('resize', () => this.onResizeEvent());
Now, when onResizeEvent()
event fires, inside it this
will refer to the control, not the window.现在,当onResizeEvent()
事件触发时,在它里面this
将引用控件,而不是窗口。
The problem is that now you can't unsubscribe.问题是现在你不能退订。 We need to keep a reference to the wrapped method to remove it:我们需要保留对包装方法的引用以将其删除:
connectedCallback() {
super.connectedCallback();
window.addEventListener('resize', this.resizeContext, { capture: false, passive: true });
}
disconnectedCallback() {
window.removeEventListener('resize', this.resizeContext);
super.disconnectedCallback();
}
private readonly resizeContext: () => void = () => this.onResizeEvent();
As this is an external event causing an update it's a better fit for a ReactiveController
to fire an update on the window events, and isolate all this resize code from your component.由于这是一个导致更新的外部事件,因此更适合ReactiveController
触发窗口事件的更新,并将所有这些调整大小的代码与您的组件隔离。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.