Comments (7)
Even Ember.Select has this issue: emberjs/ember.js#9369.
I think it would be a huge plus to support this. I also need this myself.
As a quick fix, you could try this:
Binding to .content
property usually works. What I don't like here is that the fact that the property is a promise is leaking to the templates. So see this as a workaround, not a proper definite fix.
from ember-cli-selectize.
Well, as a basic approach, you could implement optionComparePath and ensurePromise like shown below (this approach worked for me on non-multiple-selects binding the value, not the selection).
Explanation:
optionComparePath is needed, because ember-data-models are not beeing equal when using filter, although they have the same id (wtf?;). So i extended ember-cli-selectize with optionComparePath to ensure that they are seen as equal, even if they technically arent.
Multiple calls of "_valueDidChange" are avoided using "ensurePromise". Sorry for not having the time to create a nice and clean pull request with unit tests ;)
// reopen ember-cli-selectize in app.js (bad style, i know)
import EmberSelectizeComponent from 'ember-cli-selectize/components/ember-selectize';
import computed from 'ember-new-computed';
var get = Ember.get;
EmberSelectizeComponent.reopen({
optionComparePath: 'content',
_comparePath: computed('optionComparePath', function () {
return this.get('optionComparePath').replace(/^content\.?/, '');
}),
_ensurePromise: function (content) {
return new Ember.RSVP.Promise(function (resolve) {
resolve(content);
});
},
_valueDidChange: Ember.observer('value', function () {
var content = this._ensurePromise(this.get('content'));
var _this = this;
content.then(function (resolvedObject) {
var value = _this.get('value');
var valuePath = _this.get('_valuePath');
var comparePath = _this.get('_comparePath');
var selectedValue = (valuePath ? _this.get('selection.' + valuePath) : _this.get('selection'));
var selection;
if (value !== selectedValue) {
selection = resolvedObject ? resolvedObject.find(function (obj) {
if (comparePath === '') {
return value === (valuePath ? get(obj, valuePath) : obj);
}
return get(value, comparePath) === get(obj, comparePath);
}) : null;
_this.set('selection', selection);
}
});
})
});
The Controller:
// articles.js, controller
import Ember from 'ember';
export default Ember.Controller.extend({
parentArticles: function () {
var _this = this;
return this.store.filter('article', {parent: null}, function (article) {
// unpersisted not allowed
if (article.get('isNew')) {
return false;
}
// articles with a parent not allowed
if (article.get('parent.id')) {
return false;
}
// self as parent not allowed
if (article.get('id') === _this.get('model.id')) {
return false;
}
return true;
});
}.property('model')
});
The Template:
{{ember-selectize
content=parentArticles
optionValuePath="content"
optionLabelPath="content.title"
optionComparePath="content.id"
value=model.parent}}
The Model:
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
children: DS.hasMany('article', {inverse: 'parent', async: true}),
parent: DS.belongsTo('article', {inverse: 'children', async: true})
});
from ember-cli-selectize.
The general strategy would be to don't do anything until the promise resolves. If it isn't a promise, we just wrap it in a promise that always resolves and then we deal only with promises. Thanks for the code.
Minor thing, this:
return new Ember.RSVP.Promise(function (resolve) {
resolve(content);
});
could be replaced with:
return Ember.RSVP.Promise.resolve(content);
i.e, a promise that resolves immediately.
from ember-cli-selectize.
Thank you. Wow that was a quick feedback ;) Yes, Promises are the key i think...
I'd love to see the optionComparePath as a feature in one of the next releases (just as a possibility to override the default compare-behaviour).
If i should create an extra issue for that, just give me a hint.
from ember-cli-selectize.
On a second thought, I think you may be doing something unecessary.
Currently ember-selectize uses optionValuePath
to test equality.
Also, it uses selection
to hold the selected object and value
to hold its value according to value path.
I think your template should be:
Maybe the documentation should be more explicit on the selection
vs value
subject.
This is a different subject from the topic of this issue.
from ember-cli-selectize.
Well, it would take a bit more time to explain the whole thing. In short:
- I wrap ember-selectize into my own component
- I directly link the value to a belongsTo-Property on the model
- If optionValuePath would be "content.id" like you described, changing the selected option results in an ember-data error, because the property "article.parent" cannot be an integer but must be a valid model
So this is the only option:
{{ember-selectize
content=parentArticles
optionValuePath="content"
optionLabelPath="content.title"
selection=model.parent}}
But: If i compare the model article.parent (which is a relationship) with the model, store.find('article') delivers after fullfilling its promise, these two are not equal (neither with Ember.isEqual nor with ===). I did not find out why yet.
So my only option was to extend ember-cli-selectize with optionComparePath, which is used only for comparison und uses the id instead of comparing the whole object.
Perhaps my approach is totally wrong (it does not feel wrong), but i think optionComparePath would make ember-cli-selectize more flexible.
from ember-cli-selectize.
If optionValuePath would be "content.id" like you described, changing the selected option results in an ember-data error, because the property "article.parent" cannot be an integer but must be a valid model
I don't think this is true. If optionValuePath would be content.id
, then:
value
would be an integer (the model's id)selection
would be a valid model
If i compare the article.parent model (relationship) with the model, store.find returns, these are not equal (neither with Ember.isEqual nor with ===). I did not find out why yet.
When you do a this.get('model.parent')
, and parent
is a relationship, remember that you get a Promise
, not the record. Don't know if you skipped this subject for brevity, but maybe this is the root of that problem.
from ember-cli-selectize.
Related Issues (20)
- hideSelected and multiple don't work together HOT 1
- v0.5.8 broke the selectize styles HOT 4
- selectize.js:2151 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'
- multiple mode bug? HOT 2
- Selectize changing my model property to null
- Best Practice for adding/removing on a REST/API error
- add 'readOnly' to 'generalOptions ' HOT 2
- Move selectize and sifter from Bower to NPM HOT 3
- select-item action should not fire when selection promise resolves. HOT 1
- Using multiple=true with ember-changeset-validations HOT 3
- Add Support for data-dash-attributes
- Can't install due to missing dependency HOT 1
- Label truncates when second word contains letters in the first in multiple mode HOT 1
- Tooltip for list
- 2 selectors in the same template and options visible for both of them at the same time HOT 1
- Fix breaking changes in FastBoot 1.0 HOT 1
- Migration to power select HOT 1
- DEPRECATION HOT 1
- Deprecated calls to sendAction
- ember-cli-selectize triggers a Maximum Call Stack exceeded errors
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ember-cli-selectize.