2016-03-09 16 views
7

Ich benutze Aurelia, um eine dynamische Form basierend auf einem JSON zu erstellen. Das Formular wird von einem json wie die folgenden zu erzeugen:Schema-Formular mit Aurelia

Schema = [{ 
    'key': 'Name', 
    'display': 'Name', 
    'type': 'text', 
    'placeholder': 'Name', 
    'required': true 
}, 
{ 
    'key': 'IsSubscribed', 
    'display': 'Subscribed to newsletter?', 
    'type': 'checkbox', 
    'placeholder': null, 
    'required': false 
}]; 

Das Modell, das Formular zu füllen ist über einen Web-API-Service zur Verfügung. So weit, ist es mir gelungen, die folgende Vorlage zu verwenden.

Jetzt stehe ich vor Schwierigkeiten, wenn das Model ein anderes Objekt als Eigenschaft enthält. Z. B. für die Eigenschaft Adresse möchte ich ein Eingabefeld für Stadt.

Daher item.key = "Address.City".

Ich kann mit (1) Model.Address.City oder (2) Model ['Address'] ['City'] binden, die nicht möglich sind, da das Formular zur Laufzeit generiert. Ich möchte etwas wie (3) Model ['Address.City'] verwenden, damit ich Model [item.key] für die Bindung verwenden kann. Gibt es eine einfache Syntax, um dies zu erreichen?

Beispiel für eine ähnliche Anwendung in Angular Js ist Angular Schema Form

Vielen Dank im Voraus.

Antwort

7

Dies kann mit einem Bindungsverhalten erreicht werden, das versteht, was mit den Schlüsseln zu tun ist. Das Endergebnis ist, dass die Bindung wie jeder andere Bindungsausdruck funktioniert.

Hier ist ein Beispiel: https://gist.run?id=720d20b2db5adba92f62f7e665cf3b96

app.html

<template> 
    <require from="./dynamic-expression-binding-behavior"></require> 

    <label> 
    Address 1: 
    <input value.bind="model & dynamicExpression:'address.address1'"> 
    </label> 
    <label> 
    Address 2: 
    <input value.bind="model & dynamicExpression:'address.address2'"> 
    </label> 
    <label> 
    City: 
    <input value.bind="model & dynamicExpression:key"> 
    </label> 
    <label> 
    State: 
    <input value.bind="model & dynamicExpression:'address.state'"> 
    </label> 
    <label> 
    Zip: 
    <input value.bind="model & dynamicExpression:'address.zip'"> 
    </label> 
</template> 

export class App { 
    model = { 
    address: { 
     address1: '1 Main Street', 
     address2: '', 
     city: 'Burlington', 
     state: 'VT', 
     zip: '05401' 
    } 
    }; 

    key = 'address.city'; 
} 

dynamisch-Ausdruck-Bindung-behavior.js app.js

import {inject} from 'aurelia-dependency-injection'; 
import {Parser} from 'aurelia-binding'; 
import {rebaseExpression} from './expression-rebaser'; 

@inject(Parser) 
export class DynamicExpressionBindingBehavior { 
    constructor(parser) { 
    this.parser = parser; 
    } 

    bind(binding, source, rawExpression) { 
    // Parse the expression that was passed as a string argument to 
    // the binding behavior. 
    let expression = this.parser.parse(rawExpression); 

    // Rebase the expression 
    expression = rebaseExpression(expression, binding.sourceExpression); 

    // Squirrel away the binding's original expression so we can restore 
    // the binding to it's initial state later. 
    binding.originalSourceExpression = binding.sourceExpression; 

    // Replace the binding's expression. 
    binding.sourceExpression = expression; 
    } 

    unbind(binding, source) { 
    // Restore the binding to it's initial state. 
    binding.sourceExpression = binding.originalSourceExpression; 
    binding.originalSourceExpression = null; 
    } 
} 
+0

Danke, Jeremy. Es funktionierte für ein einzelnes Feld in der Form. Aber wenn ich dasselbe für mehrere Felder im Formular verwende, stehe ich vor einem Problem. Für jedes solche Feld merkt sich die Verkettung die früheren Aufrufe, z. B. erste Model.Address.City, zweite Model.Address.City.Address.State. Außerdem wird die Bindung niemals ausgelöst. Ich weiß nicht, ob es das richtige Verhalten ist oder nicht, da ich Aurelia sehr neu bin. Aber es scheint, dass die Aufräumarbeiten nicht stattfinden. Ich benutze [email protected] –

+0

Entschuldigung - Ich habe den mit dem Problem verknüpften Inhalt mit einem Fix aktualisiert. Ich habe auch ein Problem in Aurelia-Bindung geöffnet, die es einfacher machen wird, so etwas zu tun: https://github.com/aurelia/binding/issues/344 Sobald die Aurelia-Erweiterung implementiert ist, werde ich dieses Problem aktualisieren . Lassen Sie mich wissen, wenn Sie weitere Probleme haben. –

+0

Ich sah Ihre Änderung, aber ich konnte _model & dynamicExpression nicht verwenden: 'address.address1'_, da der Wert address.address1 von einer anderen Variablen kommt (say key). Und aus genau diesem Grund kam das Problem in Position, sonst könnte ich model.address.address1 direkt verwenden, um mit der Eingabe zu binden. –