是否可以在Ember Power Select中将多个参数传递给onChange操作?

时间:2019-05-22 09:34:18

标签: ember.js

我目前正在使用出色的ember-power-select作为ember-bootstrap form的一部分。

我在表单上有多个下拉项,我试图将它们的处理方式统一为一个函数,该函数可以在power-select调用中用作onChange操作:

{{#form.element 
    controlType="power-select" 
    label="Destination" 
    value=destinationSelection
    options=destinationOptions
    as |el|}}
    {{#el.control   
        onChange=(action "setDropDown")
        searchField="name"  
        as |item|}}
        {{item.name}}
    {{/el.control}}
{{/form.element}}

我的处理程序函数将根据下拉菜单的选择简单地设置一些值:

actions: {
     setDropDown(selected, string) {
      handleDropDown(selected, dropdown, this)
    }
}

function handleDropDown(selected, dropdown, controller) {
  let selection = `${dropdown}Selection`
  let modelid = `model.${dropdown}_id`

  set(controller, selection, selected)
  set(controller, modelid, selected.id)

}

为此,我确实需要能够将字符串从组件调用的setDropDown部分传递给onChange操作,否则我无法告诉处理程序函数应该在不为每个下拉列表创建操作的情况下设置哪些特定字段。

但是,当我尝试传递

之类的多个参数时
onChange=(action "setDropDown" "destination") 

onChange=(action "setDropDown" selected "destination")

我失去了以所选项目作为第一个参数的onChange动作的基本功能。

我浏览了文档,找不到任何库作者将多个参数传递给onChange操作的示例,并想知道是否有可能在不破坏库功能的情况下实现。

2 个答案:

答案 0 :(得分:1)

Ember Bootstrap's Power Select integration为您提供了类似此类用例的出色API。让我举一个例子。

让我们以国家/地区选择器为例。我们有一个国家/地区列表,该列表包含一个对象列表,该对象包含按照ISO 3166-1定义为id属性的两个字母的国家/地区代码,以及它们的名称为name的名称。所选国家/地区应在该国家/地区的POJO模型上用该国家/地区代码表示。

export default Component.extend({
  // country code of country selected or null
  selectedCountry: null,

  // Using a computed property here to ensure that the array
  // isn't shared among different instances of the compontent.
  // This isn't needed anymore if using native classes and
  // class fields.
  countries: computed(() => {
    return [
      { id: 'us', name: 'United States of America' },
      { id: 'ca', name: 'Canada' },
    ];
  }),

  // Using a computed property with getter and setter to map
  // country code to an object in countries array.
  selectedCountryObject: computed('selectedCountry', {
    get() {
      return this.countries.find((_) => _.id === this.selectedCountry);
    },
    set(key, value) {
      this.set('selectedCountry', value.id);
      return value;
    }
  }),
});

现在,我们可以按预期使用Ember Bootstrap Power Select:

{{#bs-form model=this as |form|}}  
  {{form.element controlType="power-select" property="selectedCountryObject" label="Country" options=this.countries}}
{{/bs-form}}

免责声明:我自己还没有测试过该代码,因此可能会有错别字,但我希望您能理解。

答案 1 :(得分:1)

您可以使用专门的高阶辅助函数来为ember-power-select创建一个动作,该动作最终将使用额外的参数来调用您的动作。考虑这个助手handle-dropdown

import { helper } from '@ember/component/helper';

export function invokeFunction([prop, action]) {
    return function(){
        action(prop, ...arguments);
    }
}

export default helper(invokeFunction);

所以我们在这里所做的是创建将由ember-power-select调用的函数。在此函数中,我们首先使用prop调用原始操作,然后是ember-power-select用来调用onchange函数的每个参数。

在您的模板中,将您的操作传递给power-select

时,请调用此帮助程序。
{{#power-select 
   onchange=(handle-dropdown 'foo' (action 'dropdownChanged')) 
   as |dropdown|}}

然后您的动作将会

actions: {
  dropdownChanged(keyToSet, selectedValue){
    this.set(keyToSet, selectedValue);
  }
}

这最终将称为dropdownChanged('foo', /* the selected value */)