2015-10-23 12 views
9

In meiner Anwendung habe ich eine Menge "Dienste", die ich in meinem Viewmodels injizieren kann, um einige Zeit und Redundanz zu speichern.2-Wege-Databinding in Aurelia benutzerdefinierte Elemente - binden benutzerdefiniertes Element an übergeordnete Viewmodel

Nun möchte ich noch einen Schritt weiter gehen und diese Formularelemente (Auswahl, Text, Kontrollkästchen - ein Dropdown-Menü für Starter) machen und sie in benutzerdefinierte Elemente umwandeln, wobei der Dienst nur in das benutzerdefinierte Element eingefügt wird.

Ich kann es einigermaßen funktionieren. Das benutzerdefinierte Element (in diesem Fall auswählen) wird angezeigt, wenn ich es in der "übergeordneten" Ansicht benötige. Wenn ich jedoch den ausgewählten Wert des benutzerdefinierten Auswahlelements ändere, bindet es nicht an das "übergeordnete" Ansichtsmodell, was meine Anforderung ist .

Ich möchte in der Lage sein, meinen ausgewählten Wert aus dem benutzerdefinierten Element an eine Eigenschaft auf dem "Eltern" Viewmodel über das Bind-Attribut in seiner Vorlage zu binden.

Ich werde ein wenig Code-Snippet in ein paar Minuten aktualisieren.

create.js (was ich als Elternteil Ansichtsmodell verweisen)

import {bindable} from 'aurelia-framework'; 
export class Create{ 
    heading = 'Create'; 
    @bindable myCustomElementValue = 'initial value'; 
} 

create.html (Elternansicht)

<template> 
    <require from="shared/my-custom-element"></require> 
    <my-custom selectedValue.bind="myCustomElementValue"></my-custom> 
    <p>The output of ${myCustomElementValue} should ideally be shown and changed here, as the select dropdown changes</p> 
</template> 

my-custom.js

import { inject, bindable} from 'aurelia-framework'; 
import MyService from 'my-service'; 

@inject(MyService) 
export class MyCustomCustomElement { 
    @bindable selectedValue; 

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

    selectedValueChanged(value) { 
     alert(value); 
     this.selectedValue = value; 
    } 

    async attached() { 
     this.allSelectableValues = await this.myService.getAllValues(); 
    } 
} 

Was passiert, ist zunächst die create.html view outputs "initial value", und wenn ich den Wert des benutzerdefinierten Elementes ändere, wähle den neu ausgewählten Wert e wird alarmiert, aber es aktualisiert nicht die gebundene Elternvariable, die gerade noch "Anfangswert" anzeigt.

Antwort

21

Es gibt ein paar Probleme hier:

  1. Sie müssen alle Eigenschaftsnamen Kebab-Fall im DOM aufgrund fall Unempfindlichkeit

    selected-value.bind="property"

    nicht

    selectedValue.bind="property"

  2. Sie müssen bidirektional binden. Beim Erstellen eines @bindable mit dem Dekorator ist eines der Argumente BindingMode, die Sie verwenden, um den Standard-Bindungsmodus festzulegen.

    Aurelia setzt einige vernünftige Standardwerte, z. der Standard für input value.bind=".." ist Zweiweg ohne explizit werden

    Wenn Sie keine Standardbindungsmodus einstellen möchten, können Sie einfach explizit mit Bindung:

    selected-value.two-way="prop"

Hope this hilft :)

Edit: Ich denke, dass die API ein wenig nach dieser Antwort geändert.

Der @bindable Dekorateur hat folgende sig:

bindable({ 
    name:'myProperty', 
    attribute:'my-property', 
    changeHandler:'myPropertyChanged', 
    defaultBindingMode: bindingMode.oneWay, 
    defaultValue: undefined 
}) 

Einer der besten Orte zum schnellen Nachschlagen zu überprüfen, ist der Aurelia Spickzettel in der Dokumentation:

http://aurelia.io/docs/fundamentals/cheat-sheet

+0

Wow Dank so viel. Was für eine erstaunliche Antwort. Eigentlich war das Snake-Case-Ding nur ein Tippfehler im Sample-Code, aber der .wo-Weg machte den Unterschied! : D Kann ich dich fragen, was du bevorzugst - Dekorateur oder .wo? – Dac0d3r

+2

Sie sollten den Standard-Bindungsmodus auf das einstellen, was andere Personen (oder Sie selbst) erwarten würden. Ich würde sagen, dass es in diesem Beispiel standardmäßig auf Zweiwege eingestellt ist, da es die natürlichste Verwendung Ihres Steuerelements ist - Sie möchten fast immer, dass "selected-value" in beide Richtungen bindet. So verwendet Aurelia Konventionen und es funktioniert gut. – Charleh

+0

+1 und danke für die Schlangenhülle erwähnen. Ich habe das nicht in Dokumenten erwähnt, da das Beispiel ein Wort Variablen waren. Verrückt zu werden, um eine Bindung herauszufinden, hat nicht funktioniert, wenn es genau wie die anderen getan wurde. – Danomite

Verwandte Themen