【问题标题】:Is it possible to pass multiple arguments to onChange action in Ember Power Select?是否可以将多个参数传递给 Ember Power Select 中的 onChange 操作?
【发布时间】:2019-05-22 09:34:18
【问题描述】:

我目前正在使用出色的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)

}

为了让它工作,我真的需要能够从组件调用的onChange 部分将字符串传递给setDropDown 操作,否则我无法告诉处理函数它是哪个特定字段应该在不为每个下拉菜单创建操作的情况下进行设置。

但是,当我尝试传入多个参数时,例如

onChange=(action "setDropDown" "destination") 

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

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

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

【问题讨论】:

  • 有什么理由不使用 Ember Bootstraps bs-form 组件的 model / property 方法?在这种情况下,您根本不需要 onChange 操作。
  • @jelhan 很好且有效的问题,简单的答案是当在{{#form.element}} 组件中使用ember-power-select 时,我无法真正看到代码块的外观。我真正想要摆脱这些菜单的只是让我的model.propertyName_id 成为下拉列表中所选对象的id 属性。

标签: ember.js


【解决方案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 */)

【讨论】:

  • 非常有用的答案,谢谢。供其他人参考,我刚刚在 Ember 3.8 和 Ember Power Select 2.3.3 中成功使用它。
【解决方案2】:

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

免责声明:我自己没有测试过该代码,所以可能会有错别字,但我希望你能明白。

【讨论】:

  • 感谢您扩展为示例。我现在可以看到 power-select 集成 API 是如何工作的,尽管对于我的特定用例,我认为这种实现会在应用程序的其他领域引起问题(当然你不知道这一点,因为我没有包括它在 OP 中)。这无疑帮助我更好地理解了附加功能,所以谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2012-10-12
  • 1970-01-01
  • 2013-01-16
  • 2018-03-26
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多