gpt4 book ai didi

javascript - Meteor Autoform - 禁用对象字段数组中的选择选项

转载 作者:行者123 更新时间:2023-12-02 04:52:03 24 4
gpt4 key购买 nike

如果某个选项已在其中一个对象组中被选中,我想将其禁用。

因此,如果我选择“2013”​​然后添加另一个示例,则“2013”​​在该组中将不可用,除非在原始组中更改该选项。

有没有一种我缺少的简单方法可以做到这一点?做出选择后,我是否需要 react 性地更新架构?

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}
]
}
];
}
}

},

最佳答案

概念验证

我知道这篇文章已有 3 年历史了。但是,我遇到了同样的问题,并想为所有也被这篇文章绊倒的人提供答案。

此答案只是概念证明,并未提供可用于生产应用的完整通用和高性能解决方案。

完全通用的解决方案需要对 AutoForm 中如何生成和更新选择字段选项的代码进行深入更改。


一些之前的笔记。

我正在使用 Autoform >=6,它提供 a good API立即在您的 SimpleSchema 中获取字段和表单值,而不会遇到更大的麻烦。 SimpleSchema 作为 npm 包包含在内,并且必须将 Tracker 传递给它以确保 Meteor react 性。

类似 AutoForm.getFieldValue 的函数是 react 性的,这是一个真正的巨大改进。但是,基于 react 性值 react 性地更改选择选项会导致大量更新周期并降低性能(正如我们稍后将看到的)。

使用 AutoForm.getFormValues在对象字段的选项中使用它时不起作用。在 Array 字段中工作时,它不会在 Object 字段中 react ,因此不会更新对它们的过滤。


操作选择输入数组的选项(失败)

您不能将它用于数组类型的字段。这是因为如果您更改选择选项,它将应用于数组中的所有选择实例。因此,它也将适用于您已经选择的值并将它们也删除。这使您的选择看起来总是“未选中”

您可以使用以下示例代码自行测试:

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),它们的选项将由外部函数计算。

此功能需要满足某些要求:

  • 如果没有选择,则不过滤任何选项
  • filter not the option,即当前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,
}
]
};

关于这个概念的一些说明

好:-有用- 你基本上可以将它扩展和扩展到你想要的复杂性(optgroups,samples 上的更多字段,检查其他字段与其他字段等)

差:- 表现- 绑定(bind)到给定的(或最近的)表单上下文(参见 here )- 要编写的代码比数组多得多。

关于javascript - Meteor Autoform - 禁用对象字段数组中的选择选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27259586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com