javascript - Update belongsTo relationship via native select element -
i have been trying incorporate details of brenna o'brien's ember conf 2016 talk <select>
ing ember patterns project , working simple attributes (in example below names
array of strings , model.name
attr( "string" )
):
<select onchange={{action (mut model.name) value="target.value"}}> {{#each names |name|}} <option value={{name}} selected={{eq name model.name}}>{{name}}</option> {{/each}} </select>
however, when applied belongsto
relationship , array of models:
controller:
import ember 'ember'; export default ember.controller.extend({ titles: null, init(){ this.set( "titles", this.store.peekall( "title" ) ); } });
template:
<select onchange={{action (mut model.title) value="target.value"}}> {{#each titles |title|}} <option value={{title}} selected={{eq title.id model.title.id}}> {{title.description}} </option> {{/each}} </select>
this fails; relationship value modified not set valid title. analysis, appears title
model stringified either when being handled htmlbars or when set option.value
, not (cannot?) being converted when relationship set.
i have solved (ember-twiddle) adding action controller:
actions: { title( id ){ this.set( 'model.title', this.store.peekrecord( "title", id ) ); } }
and modifying template call this:
<select onchange={{action "title" value="target.value"}}> {{#each titles |title|}} <option value={{title.id}} selected={{eq title.id model.title.id}}> {{title.description}} </option> {{/each}} </select>
however, need create function each relationship want update in way.
is there way directly set belongsto
relationship template without calling intermediate function or resorting add-ons? (if not there dry method of solving this?)
unfortunately, until have routable components, there no way without sending action component. fortunately, have ember-route-action-helper
us, , acts sort of shim routable components. (https://github.com/dockyard/ember-route-action-helper) - know said wanted avoid add-ons "solution not involve defining actions in component" available @ point in time (as far know). furthermore, it's helpful add-on in general. i'm using use case , others. bonus: when routable components feature lands, won't have refactoring. anyhow, how solved problem:
you can specify action on route, , use mixin dry. (instead of mixin, extend route , inherit that, or reopen route. opposed reopening route, because unlikely need action on every single route. avoid bloat.)
this mixin presumes model property , belongsto model references have same name, uses 1 variable: property
. if not case, you'll need add (and pass) parameter setbelongsto()
, specify parameter used set()
, peekrecord()
.
tested , works on ember-cli: 2.13.2
option 1: native select method
note: ember-route-action-helper
add-on required
// mixins/my-mixin.js import ember '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 'ember'; import setbelongstomixin '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 |title|}} <option value={{title.id}} selected={{eq title.id model.title.id}}> {{title.description}} </option> {{/each}} </select>
option 2: ember-power-select
method
note: ember-route-action-helper
add-on required
some slight differences if using ember-power-select
(https://github.com/cibernox/ember-power-select)
// mixins/my-mixin.js import ember '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 'ember'; import setbelongstomixin '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')) |title| }} {{title.description}} {{/power-select}}
edit 1: op makes use of ember-truth-helpers
add-on set selected option. (or op created own helper eq
.) first solution here uses add-on.
Comments
Post a Comment