2014-12-02 34 views
3

我想要禁用一個選項,如果它已經在其中一個對象組中選擇。流星Autoform - 禁用對象字段數組中的選擇選項

因此,如果我選擇了「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

嘿你有沒有解決這個問題? – krivar 2015-06-24 15:55:10

+0

爲了更好地理解你,你傾向於有多個具有相同選項的選擇,並且你希望他們相互依賴。我對嗎? – Roshdy 2016-12-26 03:10:38

回答

0

概念

證明我知道這個職位是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) - 更碼寫的,比一個數組。

相關問題