如果已经在其中一个对象组中选择了选项,我想要禁用该选项。
因此,如果我选择“2013”然后添加了另一个样本,那么“2013”将无法在该组中使用,除非在原始组中更改了该选项。
有一种简单的方法可以解决这个问题吗?在进行选择时,是否需要以反应方式更新架构?
samples:{
type: Array,
optional: true,
maxCount: 5
},
"samples.$":{
type: Object,
optional: true
},
"samples.$.sample":{
type:[String],
autoform: {
type: "select",
options: function () {
return [
{
optgroup: "Group",
options: [
{label: "2013", value: 2013},
{label: "2014", value: 2014},
{label: "2015", value: 2015}
]
}
];
}
}
},
答案 0 :(得分:0)
我知道这篇文章大约3岁。但是,我遇到了同样的问题,并想为所有那些偶然发现这篇文章的人提供答案。
这个答案只是一个概念证明,并没有提供可用于生产应用程序的完整通用和高性能解决方案。
完全通用的解决方案需要对AutoForm
中生成和更新选择字段选项的代码进行深入更改。
我正在使用Autoform> = 6,它提供a good API即可在SimpleSchema中立即获取字段和表单值,而不会遇到更多麻烦。 SimpleSchema
包含在npm包中,Tracker
必须传递给它,以确保流星反应性。
像AutoForm.getFieldValue这样的函数是被动的,这是一个真正伟大的改进。但是,基于无效值反应性地更改选择选项会导致大量更新周期并降低性能(我们将在后面看到)。
在Object字段的选项中使用AutoForm.getFormValues时,使用here不起作用。在Array字段中工作时,它不会在Object字段中反应,因此不会更新对它们的过滤。
您不能将其用于数组类型的字段。这是因为如果更改选择选项,它将适用于阵列中的所有选择实例。因此,它也适用于您已选择的值并将它们剥离。这使您的选择看起来总是“未选中”
您可以使用以下示例代码自行测试:
new SimpleSchema({
samples:{
type: Array,
optional: true,
maxCount: 5
},
"samples.$":{
type: String,
autoform: {
type: "select",
options: function () {
const values = AutoForm.getFormValues('sampleSchemaForm') || {};
const samples = values && values.insertDoc && values.insertDoc.samples
? values.insertDoc.samples
: [];
const mappedSamples = samples.map(x => x.sample);
const filteredOpts = [
{label: "2013", value: "2013"},
{label: "2014", value: "2014"},
{label: "2015", value: "2015"}
].filter(y => mappedSamples.indexOf(y.value) === -1);
return [
{
optgroup: "Group",
options:filteredOpts,
}
];
}
}
},
}, {tracker: Tracker});
仔细观察架构时,我看到了maxCount
属性。这让我想到,如果你有一个最大选项列表,你可以通过在samples
对象上使用固定属性来解决这个问题(顺便说一下:maxCount: 5
没有意义,当只有三个选择)。
这会导致每个选择都拥有自己的更新,而不会干扰其他选择。它需要一个外部函数,它可以跟踪所有选定的值,但结果非常简单。
请考虑以下代码:
export const SampleSchema = new SimpleSchema({
samples:{
type: Object,
optional: true,
},
"samples.a":{
type: String,
optional:true,
autoform: {
type: "select",
options: function () {
const samples = AutoForm.getFieldValue("samples");
return getOptions(samples, 'a');
}
}
},
"samples.b":{
type: String,
optional:true,
autoform: {
type: "select",
options: function () {
const samples = AutoForm.getFieldValue("samples");
return getOptions(samples, 'b');
}
}
},
"samples.c":{
type: String,
optional:true,
autoform: {
type: "select",
options: function () {
const samples = AutoForm.getFieldValue("samples");
return getOptions(samples, 'c');
}
}
},
}, {tracker: Tracker});
上面的代码有三个样本条目(a,b和c),它们的选项将由外部函数计算。
此功能需要满足某些要求:
samples
选择此功能的代码如下:
function getOptions(samples={}, prop) {
// get keys of selections to
// determine, for which one
// we will filter options
const sampleKeys = Object.keys(samples);
// get sample values to
// determine which values
// to filter here
const sampleValues = Object.values(samples);
const filteredOptiond = [
// note that values are stored as strings anyway
// so instead of parsing let's make them strings
{label: "2013", value: "2013"},
{label: "2014", value: "2014"},
{label: "2015", value: "2015"}
].filter(option => {
// case 1: nothing is selected yet
if (sampleKeys.length === 0) return true;
// case2: this selection has a
// selected option and current option
// is the selected -> keep this option
if (sampleKeys.indexOf(prop) > -1 && option.value === samples[prop])
return true;
// case 3: this selection has no value
// but others may have selected this option
return sampleValues.indexOf(option.value) === -1;
});
return [
{
optgroup: "Group",
options: filteredOptiond,
}
]
};
○:
-有用
- 您基本上可以扩展并扩展到您想要的复杂程度(选择组,samples
上的更多字段,与其他字段检查其他字段等。)
为: - 表现 - 绑定到给定(或最近的)表单上下文(请参阅Here) - 要编写的代码要多于数组代码。