2016-06-10 8 views
1

Ich habe eine Anwendung, die eng mit dem DOM verbunden ist. Ich muss die Größe und Position der Elemente verfolgen, die die Objekte repräsentieren, die hinter ihnen stehen.Zugriff auf DOM-Elemente und Kompositionslebenszyklus für Nicht-View-Modelle in Aurelia

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> 

Gibt es eine Möglichkeit, diese heute zu tun?

Antwort

1

Da ein CustomAttribute Zugriff auf den Kompositionslebenszyklus hat, können wir ein CustomAttribute erstellen, das ein Ereignis für das Element auslöst, das im Rückruf attached() ausgelöst wird.

import {autoinject} from 'aurelia-framework'; 

@inject(Element) 
export class AttachableCustomAttribute { 

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

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

Und es verwendet wie jede andere Ereignisbindung, mit der Ausnahme, dass es funktioniert nicht Blase und damit wir Trigger statt Delegaten verwenden.

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