Is there a way to subscribe to a view in order to observe resize/layout events in Aurelia? I have a canvas I would like to resize. I'm wondering if there is an "aurelia" way to do this?
I tried:
<div ref="canvasContainer" class="widget-dial-container" resize.delegate="doresize()">
<canvas ref="canvas" class="widget-dial-canvas" />
</div>
but it never calls my doresize()
method.
I've tried binding to the DOM offsetWidth and offsetHeight, but this doesn't work either (with and without @bindable canvasContainer;
in the vm)
Is there a way to subscribe to a view in order to observe resize/layout events in Aurelia? I have a canvas I would like to resize. I'm wondering if there is an "aurelia" way to do this?
I tried:
<div ref="canvasContainer" class="widget-dial-container" resize.delegate="doresize()">
<canvas ref="canvas" class="widget-dial-canvas" />
</div>
but it never calls my doresize()
method.
I've tried binding to the DOM offsetWidth and offsetHeight, but this doesn't work either (with and without @bindable canvasContainer;
in the vm)
- You can't use the resize event on a div – Kruga Commented Mar 11, 2016 at 10:35
- which is why I'm asking if aurelia has e up with a way. – Meirion Hughes Commented Mar 11, 2016 at 10:40
2 Answers
Reset to default 8The resize
event is only supported on the window
itself, as Kruga mentioned. You can attach to it in a cross-platform fashion using the Aurelia Platform Abstraction Layer's PLATFORM
object. You'll have to run jspm install aurelia-pal
to get it. If you aren't worried about cross-plat, then you can just use the window
object.
The following template and VM work for me. I implemented a throttle on the resize timer:
HTML
<template>
<div style="height: 125px; min-width: 150px; width: 100%;" ref="canvasContainer">
<canvas ref="canvas" width.one-way="canvasContainer.offsetWidth"></canvas>
</div>
</template>
TEMPLATE
import {PLATFORM} from 'aurelia-pal';
export class App {
resizeTimer = null;
resizeEventHandler = () => this.resized();
attached() {
this.resized();
PLATFORM.global.addEventListener("resize", this.resizeEventHandler);
}
detached() {
PLATFORM.global.removeEventListener("resize", this.resizeEventHandler);
}
resized() {
clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(() => {
let ctx = this.canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.font = "30px Arial";
ctx.fillText(`Width: ${this.canvas.width}`,10,50);
}, 150);
}
}
I made an add-on that makes use of a package npm:element-resize-detector
. This will detect all changes to a div's size, including those from css animations.
https://github./MeirionHughes/aurelia-resize
install it:
npm install aurelia-resize --save
add it to your config:
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.plugin('aurelia-resize');
add a method on your view-model:
foo(detail){
console.log("width=" + detail.width);
console.log("height=" + detail.height);
console.log("old width=" + detail.widthOld);
console.log("old height=" + detail.heightOld);
}
then use it by adding resizeable
attribute and binding to the resize event.
<div resizeable resize.trigger="foo($event.detail)">