概念
證明我知道這個職位是3歲左右。但是,我遇到了同樣的問題,並希望爲所有也遇到此問題的人提供答案。
這個答案僅僅是一個概念證明,並沒有提供一個完整的通用和高性能的解決方案,可以用於生產應用程序。
一個完全通用的解決方案需要深入更改在AutoForm
中生成和更新選擇字段選項的代碼。
一些現有的筆記。
我正在使用Autoform> = 6,它提供了a good API,可立即獲取SimpleSchema中的字段和表單值,而不會造成更大的麻煩。包含SimpleSchema
作爲npm包並且Tracker
必須傳遞給它以確保Meteor反應性。
像AutoForm.getFieldValue這樣的功能是被動的,這是一個很大的改進。但是,基於響應值反應性地更改選擇選項會導致很多更新週期並降低性能(正如我們稍後會看到的)。
使用AutoForm.getFormValues在對象字段的選項中使用它時不起作用。在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
延伸並擴展到您所需的複雜性(optgroups,更多的領域,覈對與其他領域等其他領域。)
爲: - 性能 - 綁定到給定(或最近的)形式的上下文(參見here) - 更碼寫的,比一個數組。
嘿你有沒有解決這個問題? – krivar 2015-06-24 15:55:10
爲了更好地理解你,你傾向於有多個具有相同選項的選擇,並且你希望他們相互依賴。我對嗎? – Roshdy 2016-12-26 03:10:38