2016-03-09 2 views
7

Я использую Aurelia для создания динамической формы на основе json. Форма генерации из JSON, как в следующем:Форма схемы с использованием Aurelia

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

модель заполнить форму можно через службу Web API. Таким образом, мне удалось использовать следующий шаблон.

<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> 

Теперь я столкнулся с трудностями, когда Модель содержит другой объект в качестве свойства. Например, для свойства Address я хотел бы ввести поле для City.

Следовательно, item.key = "Address.City".

Я могу связать с (1) Model.Address.City или (2) Model ['Address'] ['City'], которые невозможны при формировании формы во время выполнения. Я хотел бы использовать что-то вроде (3) Model ['Address.City'], чтобы я мог использовать Model [item.key] для привязки. Есть ли простой синтаксис для достижения этого?

Пример подобного применения в угловом Js является Angular Schema Form

Заранее спасибо.

ответ

7

Это может быть выполнено с помощью правила привязки, который понимает, что делать с ключами. Конечным результатом является то, что привязка будет функционировать как любое другое связывающее выражение.

Вот пример: 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'; 
} 

динамической экспрессии-связывающего 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

Спасибо, Джереми. Он работал для одного поля в форме. Но когда я использую то же самое для более чем одного поля в форме, я столкнулся с проблемой. Для каждого такого поля конкатенация запоминает предыдущие вызовы, например, сначала Model.Address.City, второй Model.Address.City.Address.State. Кроме того, unbind никогда не срабатывает. Я не знаю, является ли это правильным поведением или нет, поскольку я очень новичок в Aurelia. Но похоже, что очистка не происходит. Я использую [email protected] –

+0

Извините, что я обновил суть, связанную с проблемой исправлением. Я также открыл проблему в привязке aurelia, которая упростит сделать что-то вроде этого: https://github.com/aurelia/binding/issues/344 Как только усовершенствование Aurelia будет реализовано, я обновлю эту проблему , Дайте мне знать, если вы столкнетесь с дальнейшими проблемами. –

+0

Я видел вашу модификацию, но я не мог использовать _model & dynamicExpression: 'address.address1'_, поскольку значение address.address1 происходит от другой переменной (скажем, клавиши). И по этой причине проблема возникла, в противном случае я мог бы использовать model.address.address1 напрямую для привязки к вводу. –

Смежные вопросы