背景: 我尝试使用Aurelia创建表单。我有一个人对象,我希望能够填写数据。如果用户知道关于该家庭的一些识别信息,则他们可以在输入中输入该信息,并且将显示选择框以允许用户从该家庭中选择该特定表格的个人。然后,表单将填写它所知道的关于该个人的任何信息到输入字段中,允许用户在必要时覆盖任何信息。如果他们想要选择另一个人,表单还允许他们清除所选人员。
大多数功能似乎都按预期工作,但当我尝试允许用户清除所选人员时,我发现了一些我不会预料到的行为。
我创建了一个GistRun。底部窗格正如我所料,在用户获取数据后,选择一个人然后清除他们的选择,他们再次提供select元素。如果取消注释输入元素,您将看到用户现在 必须再次单击清除操作 才能再次看到select元素。的 为什么?
如何更新应用程序,以便用户只需要清除该人一次,再次出现选择框以允许用户进行其他选择?
如果您有Aurelia应用程序,则应该可以通过将app.html
替换为以下内容来重现此问题:
<template>
<select value.bind="val2" if.bind="opts2 && !val2">
<option repeat.for="opt of opts2" model.bind="opt">${opt.firstName}</option>
</select>
<div if.bind="!opts2 || val2">
<span>${val2.firstName}</span>
<button click.delegate="clearVal2()" if.bind="val2">Clear</button>
</div>
<button click.delegate="getOpts2()">Get</button>
<div>${val2.blah}</div>
<!--<input type="text" value.bind="val2.blah"/>-->
</template>
app.js
与此:
export class App {
opts2;
val2;
getOpts2(){
this.opts2 = [
undefined,
{
blah: 1,
firstName: 'foo',
address: {
line1: '123 Main St.'
}
},
{
blah: 2,
firstName: 'bar',
address: {
line1: '456 Other Wy.'
}
}
];
}
clearVal2(){
this.val2 = null;
}
}
非常感谢任何帮助。谢谢!
更新 如果我将输入放在自定义元素中并绑定到该元素,事情似乎按预期工作。我在表单中添加的值虽然不在一个可以使用自定义元素的位置。 I have updated the Gist with an example
如何在不需要自定义元素的情况下实现相同的功能?
答案 0 :(得分:2)
说实话,我不确定原因,但是如果在输入元素上添加if.bind =&#34; val2&#34;它会清除该值并返回选择按钮。
<input type="text" if.bind="val2" value.bind="val2.blah"/>
希望这(稍微)帮助
答案 1 :(得分:0)
假设您允许用户从列表中选择一个值或创建一个全新的条目,我倾向于将列表中选择的值和备份文本框的数据分开。每当select
的值发生更改时,我都会将支持文本框的对象的值设置为select
的值。我在示例代码中选择执行此操作的方法是在observable
绑定的值上使用select
装饰器。
以下是一个例子:https://gist.run?id=e4b594eaa452b47d9b3984e7f9b04109
<强> app.html 强>
<template>
<div>
<select value.bind="val" if.bind="opts && !val">
<option repeat.for="opt of opts" model.bind="opt">${opt.firstName}</option>
</select>
<button click.delegate="getOpts()">Get</button>
</div>
<div if.bind="!opts || person">
<span>First Name: ${person.firstName}</span>
<button click.delegate="resetForm()" if.bind="val">Clear Selection</button>
</div>
Address: <input type="text" value.bind="person.address.line1" />
<hr />
val
<pre><code>
${toJSON(val)}
</code></pre>
person
<pre><code>
${toJSON(person)}
</code></pre>
</template>
<强> app.js 强>
import {observable} from 'aurelia-framework';
export class App {
@observable val = null;
person = {};
getOpts(){
this.opts = [
null,
{
blah: 1,
firstName: 'foo',
address: {
line1: '123 Main St.'
}
},
{
blah: 2,
firstName: 'bar',
address: {
line1: '456 Other Wy.'
}
}
];
}
valChanged() {
this.person = this.val;
console.log("set person");
}
resetForm(){
this.val = null;
console.log("reset val");
}
toJSON(value) {
if(!(value === false) && !value) {
return '';
}
return JSON.stringify(value);
}
}
重置表单时,您可以看到有趣的事情发生。当我们设置person
时,Aurelia正在创建绑定到person.address.line1
所需的属性(即person = null
。但它不会创建firstName
属性,b / c在person
停止虚假之前,财产不受约束。
答案 2 :(得分:0)
此处的另一个选择是简单地使用with
属性来确定输入范围。
https://gist.run/?id=7b9d230f7d3c6dc8c13cefdd7be50c7f
<template>
<template with.bind="val.address">
<input value.bind="line1" />
</template>
</template>
虽然我同意混合选择和输入的逻辑可能不是最好的主意:)