2016-03-09 14 views
7

Sto utilizzando Aurelia per creare una forma dinamica basata su un json. La forma sta generando da un JSON come il seguente:Schema form utilizzando Aurelia

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

Il modello per compilare il modulo è disponibile tramite un servizio Web API. Quindi, sono riuscito a utilizzare il seguente modello.

<template> 

    <section class="au-animate"> 
    <h2>Edit Form</h2> 
    <form class="form-group"> 
     <div repeat.for="item of Schema" class="form-group"> 
      <label if.bind="item.type === 'text' || item.type === 'checkbox'" class="control-label" for.bind="item.key">${item.display} 
       <input class="form-control" id.bind="item.key" placeholder.bind="item.placeholder" type.bind="item.type" value.bind="Model[item.key]" />  
      </label> 
      <label if.bind="item.type === 'textarea'">${item.display} 
       <textarea placeholder.bind="item.placeholder" value.bind="Model[item.key]></textarea> 
      </label> 
      ... 
     </div> 
    </form> 
    </section> 

    </template> 

Ora sono in difficoltà, quando il modello contiene un altro oggetto come proprietà. Ad esempio, per la proprietà Indirizzo vorrei una casella di input per City.

Quindi, item.key = "Address.City".

È possibile eseguire il binding con (1) Model.Address.City o (2) Model ['Address'] ['City'] che non sono possibili poiché il modulo sta generando in fase di esecuzione. Vorrei usare qualcosa come (3) Model ['Address.City'], in modo che io possa usare Model [item.key] per il binding. C'è qualche sintassi facile per raggiungere questo?

Esempio di applicazione simile a angolare Js è Angular Schema Form

Grazie in anticipo.

risposta

7

Questo può essere eseguito con un comportamento vincolante che comprende cosa fare con i tasti. Il risultato finale è che il binding funzionerà come qualsiasi altra espressione di binding.

Ecco un esempio: 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> 

app.js

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

    key = 'address.city'; 
} 

dinamica di espressione vincolanti-behavior.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

Grazie, Jeremy. Ha funzionato per un singolo campo nel modulo. Ma quando uso lo stesso per più di un campo nel modulo, sto affrontando un problema. Per ciascun campo di questo tipo, la concatenazione ricorda le chiamate precedenti, ad esempio, first Model.Address.City, second Model.Address.City.Address.State. Inoltre, il unbind non è mai un incendio. Non so se sia il comportamento giusto o meno, dato che sono molto nuovo per l'Aurelia. Ma sembra che la pulizia non stia accadendo. Sto usando [email protected] –

+0

Mi dispiace, ho aggiornato il problema allegato al problema con una correzione. Ho anche aperto un problema in aurelia-binding che renderà più semplice fare qualcosa del genere: https://github.com/aurelia/binding/issues/344 Una volta implementato il miglioramento di Aurelia, aggiornerò questo problema . Fammi sapere se incontri altri problemi. –

+0

Ho visto la tua modifica ma non ho potuto usare _model & dynamicExpression: 'address.address1'_ come valore address.address1 sta arrivando da un'altra variabile (ad esempio key). E proprio per questo motivo, il problema è venuto fuori, altrimenti, potrei usare model.address.address1 direttamente per legare con l'input. –