Javascript 余烬电源选择自定义搜索操作并使用外部数据“选择”

Javascript 余烬电源选择自定义搜索操作并使用外部数据“选择”,javascript,ember.js,ember-power-select,Javascript,Ember.js,Ember Power Select,概述 我在一个Ember.js3.8项目中使用了它——它一半工作,一半不工作 为了使问题更具可读性,我将所有代码放在问题的底部 处境 select配置为从API端点获取数据,并为用户提供一组可能的选项供选择 所涉及的route routes/guest/new-using-ember-power-select.js会创建模型/guest.js的记录,然后,理想情况下,对表单元素templates/guests/new-using-ember-power-select.js和templates/c

概述

我在一个Ember.js3.8项目中使用了它——它一半工作,一半不工作

为了使问题更具可读性,我将所有代码放在问题的底部

处境

select配置为从API端点获取数据,并为用户提供一组可能的选项供选择

所涉及的route routes/guest/new-using-ember-power-select.js会创建模型/guest.js的记录,然后,理想情况下,对表单元素templates/guests/new-using-ember-power-select.js和templates/components/guest-form-ember-power-select.hbs所做的更改会反映回数据存储中的记录中

发行

这对文本输入很好,但我不能让它对余烬电源选择工作

在如下所示的当前配置中,用户可以:

搜索要选择的选项; 选择一个选项并单击; 将该选择反映回数据存储中的来宾实例中。但是,所做的选择没有反映在用户界面中-似乎没有做出任何选择。 我真的很感激有人指出我做错了什么。我觉得这可能是一件很小的事情,但我确实想到,我必须在组件中管理select via属性的状态,并且只有在提交表单时才更新基础数据存储。。。。我不想这样做,但我想知道这是否是最好的主意

谢谢

编辑1:我忘了说我试图改变余烬能量选择的onchange属性,这样看起来就不像这样了

onchange=(action "nationalityChangeAction")
。。。看起来像这样

onchange=(action (mut item.nationality))
其大意是:

选择的值在表单中是可见的,正如您通常期望的那样,但与我当前的工作不同,但是 放在底层数据存储记录中的值不是两个字符的国家代码,而是返回API调用的数组实例,一个具有两个属性{name:newzealand,alpha2Code:NZ}的对象。 模型

路线

模板

所选属性必须是提供给Ember Power Select的选项中包含的元素。在您的场景中,您没有使用选项属性,而是通过搜索操作设置选项,但这并没有太大区别

您的搜索操作返回一个对象数组,例如[{name:newzealand,alpha2Code:NZ}]。nationalityChangeAction将所选值设置为alpha2Code的值。因此,选项中不包括所选内容:

[{name:newzealand,alpha2Code:NZ}]。包括'NZ'//false 因此,您的电源选择的结束状态与此类似:

<PowerSelect
  @options={{array
    (hash foo="bar")
  }}
  @selected="bar"
/>
您正在做的事情的简化版本如下所示:

<PowerSelect
  @options={{array
    (hash foo="bar")
  }}
  @selected={{selected}}
  @onchange={{action (mut selected) value="foo"}}
/>
请查看使用选项和搜索之间的区别:

在这种情况下,您可以提供搜索操作而不是选项。这是唯一一种情况,在这种情况下,当用户在搜索框中键入时,选项不是必需的,将与搜索词一起调用

[……]

关于此操作,只有三件事需要知道: -您应该返回一个集合或一个从该操作解析为集合的承诺。 -您可以同时提供选项和搜索操作。这些选项将是初始选项集,但一旦用户执行搜索,将显示搜索结果

因此,如果您正在使用选项或从搜索操作返回集合,则这对您的问题没有影响。这一切都归结为具有一个选定值,该值不属于绑定到选项或由搜索操作返回的集合的一部分

这就是为什么在使用onchange=action mut item.nationality时,用户界面能够正常工作的原因。在这种情况下,item.national是指通过搜索返回到集合中选定对象的项,例如{name:newzealand,alpha2Code:NZ},而不是它的alpha2Code属性的值


我在回答中使用了。希望一切顺利。在我看来,这使阅读更容易。

我将回答显示一些差异,以及使选择在回购协议中起作用所需的更改:

要理解的关键是,在您的情况下,ember power select会收到一个块

as |country|}}
  {{country.name}}
{{/power-select}}
将调用该块来渲染每个选项,但也渲染选定的选项。在本例中,选项是具有以下形状的国家/地区对象:{name:American Samoa,alpha2Code:AS}。这就是为什么要调用{country.name}来呈现它。但是,在您的方法中,要传递的选定值不是具有name属性的对象。事实上,它甚至不是一个对象,而是字符串,就像美属萨摩亚的情况一样,因此可以输出字符串的name属性

在您的情况下,您存储的国家代码信息不足以在select的触发器中显示一个漂亮的美属萨摩亚, 因为你在搜索之前不知道国家,所以你不能用国家代码查找国家

如果您没有编辑表单,我的建议是将整个选定国家/地区存储在您传递给选定国家/地区的属性中

只要您不想编辑您以前创建的用户(可能是几周前创建的用户)的国籍,此功能就可以工作。在这种情况下,您将没有对国家的引用,只有国家代码。在这种情况下,我建议将selected设置为一个computed属性,如果API允许的话,该属性将返回一个承诺,解析为带有用户国家代码的country对象。看起来确实如此,所以最好的解决方案是

diff --git a/app/components/guest-form-ember-power-select.js b/app/components/guest-form-ember-power-select.js
index edf9390..f889734 100644
--- a/app/components/guest-form-ember-power-select.js
+++ b/app/components/guest-form-ember-power-select.js
@@ -1,4 +1,5 @@
 import Component from '@ember/component';
+import { computed } from '@ember/object';

 export default Component.extend({
   buttonLabel: 'Save',
@@ -25,6 +26,16 @@ export default Component.extend({
   //messages
   nameOfErrMsgDspCntrl : 'errMsgDspCntrl',

+  nationality: computed('item.nationality', function() {
+    let countryCode = this.get('item.nationality');
+    if (countryCode) {
+      return fetch(`https://restcountries.eu/rest/v2/alpha/${countryCode}?fields=name;alpha2Code`)
+        .then(function (response) {
+          return response.json();
+        });
+    }
+  }),
+

最后一个将获取您知道代码所在国家的信息。

谢谢您的回复,我非常感谢。我想知道你能否把你的答案再详细一点?从您所说的内容中,我意识到有必要包含一个“options”属性,并且必须包含一个数组。我不太清楚数组应该包含什么。我认为,如果我在“Z”上搜索并从结果列表中选择“新西兰”条目,那么不仅“选定”属性的值应为“NZ”,而且。。。可能地“options”应该是一个单元素数组“[{alpha2code:'NZ'}]?谢谢。这不是选项和搜索的问题。在这种情况下,两者的工作原理相同。如果传递搜索操作处理程序,则可以忽略选项。在这种情况下,选项将由返回搜索操作的Ember Power Select填充。但在这两种情况下,所选属性的值必须包含在选项中才能显示。这并不是说你使用的是一个对象数组作为搜索返回的选项,而是一个选择的字符串。我很感激你的评论,但我现在很困惑。我想我们要说的是,options属性需要包含搜索返回的相同对象的数组?在搜索完成之前,我不知道如何才能做到这一点。我只是想知道你是否可以通过编辑你的答案来表达你的建议,使它使用与我使用的相同的变量?尝试扩展我的答案。不要被搜索和选项弄糊涂。这与你的问题无关。这一切都是关于拥有一个不包括所选项目的选项集合。谢谢。我今天没有机会看这个项目,但我会在周末看,我会在完成后更新这个问题。再次感谢。非常感谢你的帮助,米格尔,非常感谢。
//app/components/guest-form-ember-power-select.js
import Component from '@ember/component';

export default Component.extend({
    actions:{
        searchCountries(term) {
          //Response to :
          //
          //https://restcountries.eu/rest/v2/name/z?fields=name;alpha2Code
          //
          //
          //looks like this
          //  [
          //    ...
          //    {"name":"New Zealand","alpha2Code":"NZ"}
          //    ...
          //  ]
          //

          let url = `https://restcountries.eu/rest/v2/name/${term}?fields=name;alpha2Code`
          let dbg = fetch(url)
            .then(function(response) {
              return response.json();
            });
          return dbg;
        },
        nationalityChangeAction(slctn){
            this.sendAction('changeNationalityHandler', slctn.alpha2Code);
        },
    }
});
<PowerSelect
  @options={{array
    (hash foo="bar")
  }}
  @selected="bar"
/>
<PowerSelect
  @options={{array
    (hash foo="bar")
  }}
  @selected={{selected}}
  @onchange={{action (mut selected) value="foo"}}
/>
as |country|}}
  {{country.name}}
{{/power-select}}
diff --git a/app/components/guest-form-ember-power-select.js b/app/components/guest-form-ember-power-select.js
index edf9390..2467d85 100644
--- a/app/components/guest-form-ember-power-select.js
+++ b/app/components/guest-form-ember-power-select.js
@@ -25,6 +25,8 @@ export default Component.extend({
   //messages
   nameOfErrMsgDspCntrl : 'errMsgDspCntrl',

+  nationality: undefined,
+
   actions:{

     searchCountries(term) {
@@ -73,7 +75,7 @@ export default Component.extend({
     },

     nationalityChangeAction(slctn){
-      //this.set(this.myValue, slctn);
+      this.set('nationality', slctn);
       this.sendAction('changeNationalityHandler', slctn.alpha2Code);
     },

diff --git a/app/templates/components/guest-form-ember-power-select.hbs b/app/templates/components/guest-form-ember-power-select.hbs
index 56f007d..5c69834 100644
--- a/app/templates/components/guest-form-ember-power-select.hbs
+++ b/app/templates/components/guest-form-ember-power-select.hbs
@@ -24,7 +24,7 @@
       {{#power-select
         searchPlaceholder="Text to provide user info about what they can search on"
         search=(action "searchCountries")
-        selected=item.nationality
+        selected=nationality
         onchange=(action "nationalityChangeAction")
         as |countries|
       }}
@@ -36,14 +36,14 @@
diff --git a/app/components/guest-form-ember-power-select.js b/app/components/guest-form-ember-power-select.js
index edf9390..f889734 100644
--- a/app/components/guest-form-ember-power-select.js
+++ b/app/components/guest-form-ember-power-select.js
@@ -1,4 +1,5 @@
 import Component from '@ember/component';
+import { computed } from '@ember/object';

 export default Component.extend({
   buttonLabel: 'Save',
@@ -25,6 +26,16 @@ export default Component.extend({
   //messages
   nameOfErrMsgDspCntrl : 'errMsgDspCntrl',

+  nationality: computed('item.nationality', function() {
+    let countryCode = this.get('item.nationality');
+    if (countryCode) {
+      return fetch(`https://restcountries.eu/rest/v2/alpha/${countryCode}?fields=name;alpha2Code`)
+        .then(function (response) {
+          return response.json();
+        });
+    }
+  }),
+