Vererbung - Wie kann man in Aurelia bindbare Eigenschaften „vererben“?
Ich entwickle eine Aurelia-Anwendung mit TypeScript. In dieser Anwendung habe ich eine Reihe von benutzerdefinierten Elementen definiert, die jeweils eine Reihe von bindbaren Eigenschaften gemeinsam haben, die in CSS-Einstellungen übersetzt werden, wie im folgenden vereinfachten Beispiel gezeigt:
import {computedFrom, bindable, autoinject} from 'aurelia-framework';
@autoinject
export class MyCustomElement {
@bindable span: number;
@computedFrom('span')
get width() {
return this.span? this.span* 26 : 0;
}
// Leaving out a whole bunch of other code for sake of readability
}
Der HTML-Code für dieses Element sieht ungefähr so aus:
<template>
<div css="width: ${width}px;">
<svg xmlns="http://www.w3.org/2000/svg" css="width: ${width}px;">
</svg>
</div>
</template>
Also brauche ich den Wert der berechneten Eigenschaft mehrmals im gesamten HTML-Template des benutzerdefinierten Elements.
Jetzt benötigen auch andere Elemente die span- und die width-Eigenschaft. Soweit ich beim Lesen von GitHub verstanden habe: Aurelia Issue #210 wird die Vererbung von bindbaren Eigenschaften noch nicht unterstützt. Wie Rob Eisenberg erklärte, wäre der Weg hier die Verwendung von Komposition. Aber wenn ich das benutze, müsste ich trotzdem sowohl die span- als auch die width-Eigenschaft implementieren und außerdem eine Komponente über Dependency Injection importieren, die nur die Funktionalität des tatsächlichen Berechnens des linken Randes hinzufügt. Also führt dieser Ansatz insgesamt immer noch zu viel Copy-und-Paste-Code.
Gibt es einen besseren Weg, dies anzugehen?
Ich habe darüber nachgedacht, benutzerdefinierte Attribute dafür zu verwenden, nachdem ich einen Hinweis von @AureliaEffect auf Twitter bekommen habe, aber das wird mich immer noch nicht daran hindern, jedes der erforderlichen Eigenschaften auf dem Element zu implementieren, um daran im Template des Elements binden zu können.
Eine kurze Erklärung zum Business-Case dahinter (auch bekannt als "Warum habe ich diesen Ansatz gewählt"): Nutzer meiner Anwendung können ein Gleislayout erstellen, wie man es in elektronischen Stellwerksystemen findet. Dabei ist es notwendig, die Breite von Elementen oder deren Versatz in einigen generischen Einheiten anzugeben, nicht in Pixeln. Außerdem müssen diese Eigenschaften pro Element und nicht pro Elementklasse angegeben werden.
(Es gibt hier eine weitere Frage auf StackOverflow, die ein etwas ähnliches Thema behandelt, jedoch mit einem Ansatz, der in meinem Szenario nicht funktioniert: Verwendung des @bindable-Attributs in einer Kindklasse in Aurelia)
Antwort #1
Vielleicht siehst du es seit dieser Frage, aber es gibt gerade eine aktive Diskussion darüber auf GitHub, mit eventuell bald kommendem PR. Du kannst die Diskussion hier verfolgen: https://github.com/aurelia/templating/pull/507#issuecomment-297163265