访问 Aurelia 中非 viewModel 的 DOM 个元素和合成生命周期

Accessing DOM elements and composition lifecycle for non-viewModels in Aurelia

我有一个与 DOM 密切相关的应用程序。我需要跟踪代表其背后对象的元素的大小和位置。

myViewModel.js

export class MyViewModel {

    // my root view model has important properties 
    // that all other functions and objects need to use
    constructor() {
        this.importantProperty = 'veryimportant';
        this.things = [];
    }

    // i create things in the view model that are
    // represented in the dom
    createThing() {
        this.things.push({
            isAThing: true
        });
    }

    // i do things with things in the view model 
    // that depend strongly on the root view model
    doSomethingWithThing(thing, property) {
        thing[property] = `${this.importantProperty}${property}`;
    }

    // but i need to know all about the dom representation
    // of the things in the view model
    doAnotherThingWithThing(thing) {
        console.log(`the height of the thing is ${thing.height}`);
    }

    lookAndSeeWhatSizeThisThingIs(element, thing) {
        thing.height = element.clientHeight;
        thing.width = element.clientWidth;
        console.assert('That was easy!');
    }
}

myViewModel.html

<template>

    <!-- these things can change in size and shape, and I have
        no idea what they will be until runtime
    <div repeat.for="thing of things"

        <!-- so ideally I'd like to call something like this -->
        composed.delegate="lookAndSeeWhatSizeThisThingIs($element, thing)">

        <img src="img/${$index}.png" />
    </div>

</div>

今天有办法做到这一点吗?

由于 CustomAttribute 可以访问组合生命周期,我们可以创建一个 CustomAttribute 来触发在 attached() 回调中触发的元素上的事件。

import {autoinject} from 'aurelia-framework';

@inject(Element)
export class AttachableCustomAttribute {

    constructor(element) {
        this.element = element;
    }

    attached() {
      this.element.dispatchEvent(
          new CustomEvent('attached'));
    }
}

并像使用任何其他事件绑定一样使用它,除了它不会冒泡,因此我们必须使用触发器而不是委托。

<div repeat.for="thing of things"
    attached.trigger="lookAndSeeWhatSizeThisThingIs($event, thing)" attachable>
    <img src="img/${$index}.png" />
</div>