我在Aurelia建立一个多步骤表单,每个页面显示一个问题。
我对每个问题使用相同的视图,if
语句确定要显示的表单字段的类型。
当我尝试将我的问题数据绑定到一个多选元素时,Aurelia会抛出错误并说“#34;只有null或Array实例可以绑定到多选。"。
真正奇怪的是,如果第一个问题是多重选择,我不会得到错误,直到我遇到非多选问题,然后再回到多选问题。
我可以通过为此路线设置activationStrategy: 'replace'
来解决整个问题,但我真的不想这样做。
重要的代码如下:
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
@inject(Router)
export class Form {
constructor (router) {
this.router = router;
this.active = 0;
this.field = null;
this.fields = [
{
type: 'text',
value: null
},
{
type: 'select',
value: [],
options: [
'foo',
'bar'
]
},
{
type: 'select',
value: [],
options: [
'foo',
'bar'
]
},
{
type: 'text',
value: null
},
];
}
activate (routeParams) {
this.active = routeParams.fieldIndex || 0;
this.active = parseInt(this.active);
this.field = this.fields[this.active];
}
prev () {
if (typeof this.fields[this.active - 1] !== 'undefined') {
this.router.navigateToRoute('form', {
fieldIndex: this.active - 1
});
return true;
}
else {
return false;
}
}
next () {
if (typeof this.fields[this.active + 1] !== 'undefined') {
this.router.navigateToRoute('form', {
fieldIndex: this.active + 1
});
return true;
}
else {
return false;
}
}
}
模板:
<template>
<div class="select" if.bind="field.type == 'select'">
<select value.bind="field.value" multiple="multiple">
<option repeat.for="option of field.options" value.bind="option">${option}</option>
</select>
</div>
<div class="text" if.bind="field.type == 'text'">
<input type="text" value.bind="field.value">
</div>
<a click.delegate="prev()">Previous</a> | <a click.delegate="next()">Next</a>
</template>
但您可能想查看GistRun:https://gist.run/?id=4d7a0842929dc4086153e29e03afbb7a以便更好地理解。
尝试将第一个问题设置为多选,您会注意到错误消失(直到您回到它)。您也可以在app.js中尝试activationStrategy
,如上所述。
为什么会发生这种情况,我该如何解决?
另请注意,在我的真实应用中,我实际上使用的是compose
而不是if
,但尝试了两者并且两者都产生相同的错误。在评估if之前,似乎似乎绑定了选择值,导致错误显示,因为text
字段类型缺少options
数组。
答案 0 :(得分:1)
有点晚了但是我想给出一个建议 - 对于SELECT多选,你应该将绑定变量与多选择器分离以防止这些错误。
例如,如果您在自定义元素中绑定到“selected”,则它们应绑定到:
<select multiple value.two-way="selectedDecoupled">
然后当实际变量'selected'发生变化时,如果绑定值是数组,它只会在自定义元素中更改:
selectedChanged( newV, oldV ){
if( typeof newV =='object' )
this.selectedDecoupled = newV;
else
this.selectedDecoupled = [];
$(this.SELECT).val(this.selectedDecoupled ).trigger('change');
}
与自定义select2元素一起使用的示例:
答案 1 :(得分:0)
好的,所以事实证明交换HTML的顺序,并在<{em> select
之后放置input
解决了这个问题。
Jeremy Danyow这样解释:
当Form.field更改时,订阅该属性的绑定将按顺序进行更改。这意味着选择和输入都在页面上的时间段。 html输入元素将空值转换为空字符串,这反过来导致field.value为空字符串,这使得多选择抛出。
追踪imo非常棘手,但我很高兴Aurelia开发者对Github非常有帮助。