gpt4 book ai didi

javascript - 通过 native 选择元素更新 belongsTo 关系

转载 作者:行者123 更新时间:2023-11-30 11:53:56 26 4
gpt4 key购买 nike

我一直在尝试合并 Brenna O'Brien 的详细信息2016 年 Ember Conf 演讲 <select> ing Good Ember Patterns进入一个项目,它适用于简单的属性(在下面的示例中,names 是一个字符串数组,model.name 是一个 attr( "string" ) ):

<select onchange={{action (mut model.name) value="target.value"}}>
{{#each names as |name|}}
<option value={{name}} selected={{eq name model.name}}>{{name}}</option>
{{/each}}
</select>

但是,当这应用于 belongsTo关系和一系列模型:

Controller :

import Ember from 'ember';

export default Ember.Controller.extend({
titles: null,
init(){
this.set( "titles", this.store.peekAll( "title" ) );
}
});

模板:

<select onchange={{action (mut model.title) value="target.value"}}>
{{#each titles as |title|}}
<option value={{title}} selected={{eq title.id model.title.id}}>
{{title.description}}
</option>
{{/each}}
</select>

这失败了;关系值已修改,但未设置为有效标题。从一些分析来看,似乎 title模型在由 HTMLBars 处理或设置为 option.value 时被字符串化并且这不会(不能?)在设置关系时被转换回来。

我目前已经通过向 Controller 添加一个 Action 解决了它(Ember-Twiddle):

actions: {
title( id ){
this.set( 'model.title', this.store.peekRecord( "title", id ) );
}
}

并修改模板来调用它:

<select onchange={{action "title" value="target.value"}}>
{{#each titles as |title|}}
<option value={{title.id}} selected={{eq title.id model.title.id}}>
{{title.description}}
</option>
{{/each}}
</select>

但是,然后我需要为我想以这种方式更新的每个关系创建一个函数。

有没有办法直接设置一个belongsTo在不调用中间函数或求助于附加组件的情况下从模板建立关系? (如果没有,那么是否有解决此问题的 DRY 方法?)

最佳答案

不幸的是,在我们拥有可路由的组件之前,如果不从组件发送一个 Action ,就无法做到这一点。幸运的是,我们有 ember-route-action-helper 来帮助我们,它可以作为可路由组件的垫片。 ( https://github.com/DockYard/ember-route-action-helper ) - 我知道你说过你想避免加载项,但这是目前唯一可用的“不涉及在组件中定义操作的解决方案”(据我所知)。此外,它通常是一个非常有用的附加组件。我将它用于此用例和其他用例。奖励:当可路由组件功能落地时,您实际上不必进行任何重构。无论如何,这就是我解决这个问题的方法:

您可以在路由上指定操作,并为 DRY 使用 Mixin。(除了 Mixin,您还可以扩展 Route 并从中继承,或者您可以重新打开 Route。我将反对重新打开路线,因为您不太可能在每条路线上都需要此操作。避免膨胀。)

此 Mixin 假定您的模型属性和它引用的 belongsTo 模型将始终具有相同的名称,因此仅使用一个变量:property。如果不是这种情况,您需要将另一个参数添加(并传递)到 setBelongsTo() 并指定哪个参数用于 set()peekRecord().

ember-cli: 2.13.2 上测试并工作

选项 1: native 选择方法

注意:需要 ember-route-action-helper 附加组件

// mixins/my-mixin.js

import Ember from 'ember';

export default Ember.Mixin.create({
actions: {
setBelongsTo(model, property, value) {
this.get('controller').get(model).set(property, this.store.peekRecord(property, value));
}
}
});
// routes/my-route.js

import Ember from 'ember';
import SetBelongsToMixin from 'myApp/mixins/set-belongs-to';

export default Ember.Route.extend(SetBelongsToMixin, {
model() {
return this.get('store')find(...);
}
});
// templates/my-route.hbs

<select onchange={{action (route-action 'setBelongsTo' 'model' 'title') value="target.value"}}>
{{#each titles as |title|}}
<option value={{title.id}} selected={{eq title.id model.title.id}}>
{{title.description}}
</option>
{{/each}}
</select>

选项 2:ember-power-select 方法

注意:需要 ember-route-action-helper 附加组件

如果使用 ember-power-select ( https://github.com/cibernox/ember-power-select ) 会有一些细微差别

// mixins/my-mixin.js

import Ember from 'ember';

export default Ember.Mixin.create({
actions: {
setBelongsTo(model, property, value) {
this.get('controller').get(model).set(property, value);
}
}
});
// routes/my-route.js

import Ember from 'ember';
import SetBelongsToMixin from 'myApp/mixins/set-belongs-to';

export default Ember.Route.extend(SetBelongsToMixin, {
model() {
return this.get('store')find(...);
}
});
// templates/my-route.hbs

{{#power-select
options=titles
selected=model.title
onchange=(action (route-action 'setBelongsTo' 'model' 'title'))
as |title|
}}
{{title.description}}
{{/power-select}}

编辑 1:OP 使用 ember-truth-helpers 插件来设置所选选项。 (或者 OP 为 eq 创建了他们自己的助手。)这里的第一个解决方案也使用了这个插件。

关于javascript - 通过 native 选择元素更新 belongsTo 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38631440/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com