当前位置: 首页 > 工具软件 > emberx-select > 使用案例 >

emberx-select Uncaught TypeError: this.get(...) is not a function的解决方案

施景同
2023-12-01

说起来也挺奇怪的,按照书上的写法再次报错,这书就不能靠谱一点……

书上的例子就不放了,直接上解决方案吧。我在x-select的issue里发现了这么一条:

Hey @newton3, if you’re using x-select 3.0 you should be using contextual components. If you update your HBS to this does it still throw the same error?

{{#x-select action='selectAppType' id="app-type-select" value=model.AppType class="form-control" as |xs|}}
  {{#each model.AppTypes as |appType|}} {{log appType}}
    {{#xs.option value=appType}}
      {{appType}}
    {{/xs.option}}
  {{/each}}
{{/x-select}}

目前最新版的x-select是3.1.1,正好适用于这个方案。简单概括下来,这个解决方案就是将x-select重新包装一遍,以此让ember能够获得其中的get方法(注意到后面的|xs|声明),其实和别的包装对象的意义是大致相同的。从某个意义上说,和TypeScript中某些特殊的类型转换必须先转换成any再转换成目标类型有一点相似,不过这就扯远了。

事实上,作者也给出了解释:

Absolutely! Think of it as a component “wrapping” a component. x-option will always be used as a child of x-select. Since that will always be true we can do things like automatically pass the instance of x-select down to x-option. We also register x-option with x-select.

而且官方文档也改成这种写法了……书上那种写法不知道是哪一年的老黄历了。所以书上那个例子按照上面的改造一下,就能解决:

{{#x-select value=model.sighting.cryptid
                    class="form-control" as |xs|}}
	{{#xs.option}}Select Cryptid{{/xs.option}}
	{{#each model.cryptids as |cryptid|}}
		{{#xs.option value=cryptid}}{{cryptid.name}}{{/xs.option}}
	{{/each}}
{{/x-select}}

而且看文档上面说,还有更新的写法(要求ember版本>=3.4)。至于这个语法模仿了谁……大家都清楚,就不多说了(笑):

<XSelect @value={{bob}} @onChange={{action "selectPerson"}} as |xs|>
  <xs.option @value={{fred}}>Fred Flintstone</xs.option>
  <xs.option @value={{bob}}>Bob Newhart</xs.option>
</XSelect>

当然,改完之后虽然不报错了,但是会有deprecate的提示。这个就无能为力了,x-select的作者采用了即将废弃的写法,我们也没有办法,不是吗。而且这项目我感觉也快凉了,最近一次提交都是年初的事了……

参考资料

  1. x-select.js:151 Uncaught TypeError: Cannot read property ‘is’ of undefined
 类似资料: