Javascript Aurelia ValueConverter fromView与multi-select混淆
我试图在多选表单的上下文中使用和理解Aurelia ValueConverter。我本以为是直截了当的事情,结果却成了对我的挑战 我有一个表单来创建一个新政,它通过多选输入字段分配了多个类别。我已经将表单的输出绑定到新的_deal.categorizations中(在数据库中,deals通过categorizations拥有categories) 现在,在创建时,通过一个“暴力”方法,我将在发布到API之前将每个类别ID转换为一个{category_ID:ID}对象 仅记录POST输出的示例:Javascript Aurelia ValueConverter fromView与multi-select混淆,javascript,aurelia,Javascript,Aurelia,我试图在多选表单的上下文中使用和理解Aurelia ValueConverter。我本以为是直截了当的事情,结果却成了对我的挑战 我有一个表单来创建一个新政,它通过多选输入字段分配了多个类别。我已经将表单的输出绑定到新的_deal.categorizations中(在数据库中,deals通过categorizations拥有categories) 现在,在创建时,通过一个“暴力”方法,我将在发布到API之前将每个类别ID转换为一个{category_ID:ID}对象 仅记录POST输出的示例:
create(){
var categorizations = this.new_deal.categorizations;
this.new_deal.categorizations = categorizations.map(function (e) {
return {category_id: e}
});
logger.debug ('POST: ', JSON.stringify(this.new_deal));
}
示例输出:
POST: {"name":"new deal","categorizations":[{"category_id":"1"},{"category_id":"2"}]}
但我认为这最好通过价值转换器来实现
Plunker有完整的代码,但基本上是:
app.js:
export class App {
constructor(){
this.categories = [{id: 1, name: 'test1'}, {id: 2, name: 'test2'}];
this.new_deal = {
name: 'new deal',
categorizations: null,
};
}
create(){
var categorizations = this.new_deal.categorizations;
this.new_deal.categorizations = categorizations.map(function (e) {return {category_id: e}});
logger.debug ('POST: ', JSON.stringify(this.new_deal));
}
create2(){
logger.debug ('POST: ', JSON.stringify(this.new_deal));
}
}
export class CategoryToIDValueConverter {
fromView(id) {
return id ? id: null;
}
}
和app.html:
<template>
<h1>Testing ValueConverter</h1>
<h3 >New Brute Force Deal</h3>
<form role="form">
<label>Name</label>
<input type="text" placeholder="Ex. Buy One Get One Free" value.bind="new_deal.name">
<label>Categories</label>
<select value.bind="new_deal.categorizations" multiple size="2">
<option repeat.for="category of categories" value.bind="category.id">${category.name}</option>
</select>
</form>
<button type="submit" click.delegate="create()">Save</button>
<h3>New ValueConverter Deal</h3>
<form role="form">
<label>Name</label>
<input type="text" placeholder="Ex. Buy One Get One Free" value.bind="new_deal.name">
<label>Categories</label>
<select class="form-control" value.bind="new_deal.categorizations | categoryToID" multiple size="2">
<option repeat.for="category of categories" value.bind="category.id">${category.name}</option>
</select>
</form>
<button class="btn btn-success" type="submit" click.delegate="create2()">Save</button>
</template>
在app.js中的fromView中,我认为我可以更改:
return id ? id: null;
要返回对象而不是单个值,请执行以下操作:
return id ? {category_id: id} : null
但这导致了这个错误:
Uncaught Error: Only null or Array instances can be bound to a multi-select.
进一步检查后,id看起来像是从视图中以数组的形式出现
因此,我将fromView修改为:
fromView(id) {
if(id){
var categorizations = [];
id.forEach(function(cat_id){
categorizations.push({category_id: cat_id})
});
logger.debug(categorizations);
logger.debug(Object.prototype.toString.call(categorizations));
return categorizations;
} else { return null; }
}
}
尝试期望一个数组,然后构建一个要返回的分类对象数组,但正如您在中所看到的,它会在您单击时丢失选择(尽管调试日志显示正在创建的对象)。您有一个类别对象数组,每个类别对象都有一个
名称(字符串)和id
(数字)。这些将用于填充允许多个选择的选择元素:
导出类应用程序{
类别=[
{id:1,名称:'test1'},
{id:2,名称:'test2'}
];
}
${category.name}
交易对象由名称
(字符串)和分类
组成。分类对象如下所示:{category\u id:1}
导出类应用程序{
类别=[
{id:1,名称:'test1'},
{id:2,名称:'test2'}];
交易={
名称:“新政”,
分类:[],
}
}
我们希望将select元素的值绑定到deal对象的分类中,deal对象的分类是一个对象数组。这意味着每个select元素的选项都需要有一个对象“值”。HTMLOptionElement的value属性仅接受字符串。我们分配给它的任何内容都将被强制为字符串。我们可以将分类对象存储在一个特殊的模型
属性中,该属性可以处理任何类型。有关这方面的更多信息,请参阅
${category.name}
最后,我们需要将select元素的值绑定到deal对象的分类:
${category.name}
总之,视图和视图模型如下所示:
导出类应用程序{
类别=[
{id:1,名称:'test1'},
{id:2,名称:'test2'}];
交易={
名称:“新政”,
分类:[],
}
createDeal(){
警报(JSON.stringify(this.deal,null,2));
}
}
名称
类别
${category.name}
拯救
这里有一个正在工作的plunker:在Aurelia Gitter频道的帮助下解决了这个问题。因此,我希望fromView方法中有一个数组,但我也需要ValueConverter中有一个toView方法
导出类CategoryToIDValueConverter{
托维尤(猫){
如果(猫){
var-id=[];
cats.forEach(功能(分类){
id.push(categorization.category\u id);
});
返回ID;
}else{return null;}
}
fromView(id){
如果(id){
var分类=[];
id.forEach(功能(类别id){
push({category\u id:cat\u id})
});
返回分类;
}else{return null;}
}
}
我也尝试过,但我最初认为需要将转换器添加到表单的选择行和选项行,如下所示:
${category.name}
但这实际上是不正确的。我只需要将categoryToID ValueConverter应用于select行,一切都按预期进行
显示暴力方法如何在单击“保存”之前不会更改模型,并且ValueConverter会在您更改选择时随时更改模型
最终app.js
从'aurelia framework'导入{LogManager};
让logger=LogManager.getLogger('testItems');
导出类应用程序{
构造函数(){
this.categories=[{id:1,名称:'test1'},{id:2,名称:'test2'}];
这项新交易={
名称:“新政”,
分类:[],
};
setInterval(()=>this.debug=JSON.stringify(this.new_deal,null,2),100);
}
创建(){
var分类=此.new_deal.categorizations;
this.new_deal.categorizations=categorizations.map(函数(e){return{category_id:e});
警报(JSON.stringify(this.new_deal,null,2));
}
create2(){
警报(JSON.stringify(this.new_deal,null,2));
}
}
导出类CategoryToIDValueConverter{
托维尤(猫){
如果(猫){
var-id=[];
cats.forEach(功能(分类){
id.push(categorization.category\u id);
});
返回ID;
}else{return null;}
}
fromView(id){
如果(id){
var分类=[];
id.forEach(功能(类别id){
push({category\u id:cat\u id})
});
返回分类;
}else{return null;}
}
}
Final app.html
测试值转换器
新暴力交易
名称
类别
${category.name}
拯救
新价值转换器交易
名称
类别
${category.name}
拯救
我已经把它用到了您描述的地方
fromView(id) {
if(id){
var categorizations = [];
id.forEach(function(cat_id){
categorizations.push({category_id: cat_id})
});
logger.debug(categorizations);
logger.debug(Object.prototype.toString.call(categorizations));
return categorizations;
} else { return null; }
}
}