是否可以将多个参数传递给Ember Power Select中的Onchange动作



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

我在表单上有多个下拉列表项目,我正在尝试将它们处理成单个函数,该功能可以用作功率选择调用中的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)
}

为了使其工作,我真的需要能够从组件调用的onChange部分将字符串传递给setDropDown操作,否则我无法告诉处理程序函数,该功能应该在没有哪个特定字段的情况下设置每个下拉列表创建一个动作。

但是,当我尝试传递

等多个参数时
onChange=(action "setDropDown" "destination") 

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

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

我浏览了文档,找不到图书馆作者将多个参数传递到onChange操作中的任何示例,并想知道是否可以在不破坏库的功能的情况下进行。

您可以使用专门的高阶助手功能为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 */)

ember bootstrap的功率选择集成为您提供了一个不错的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选择:

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

免责声明:尚未亲自测试该代码,所以可能会有错别字,但我希望您明白。

您可以在模板中添加第二个参数。所选选项将自动发送到该函数。

  <PowerSelect
    @selected={{this.selectedPrice}}
    @options={{this.priceRange}}
    @onChange={{fn this.choosePrice "minPrice"}}
    class="w-64"
    as |price|
  >
    {{price.title}}
  </PowerSelect>

然后创建您的函数以处理单击,您需要定义两个参数。您在模板中定义的参数将始终首先出现,因此应该是您的第一个参数。

  @action
  choosePrice(type, price) {
    // type will be 'minPrice'
    // price will be the option you selected
  }

最新更新