Skip to content

Instantly share code, notes, and snippets.

@jgwhite
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgwhite/254f8474dd6c3c6828bf to your computer and use it in GitHub Desktop.
Save jgwhite/254f8474dd6c3c6828bf to your computer and use it in GitHub Desktop.
Observation chain breaks
import Ember from 'ember';
const { computed, typeOf } = Ember;
export default Ember.Component.extend({
value: computed({
set(param, value) {
switch(typeOf(value)) {
case "string":
this._value = value === 'foo' ? 'bar' : value;
break;
case "boolean":
this._value = new Set([String(value)]);
break;
case 'null':
this._value = null;
break;
default:
this._value = value;
}
return value;
},
get() {
return this._value;
}
})
});
import Ember from 'ember';
const { on } = Ember;
export default Ember.Controller.extend({
appName:'Observation Change Falls Over',
myProp: 'to start with',
mySet: null,
_mySetInit: on('init', function() {
this.set('mySet', new Set(['one','two','three']));
}),
actions: {
setValue: function(value) {
this.set('myProp', value);
}
}
});
<h1>{{appName}}</h1>
<p>
When you have a computed property (w/ getter and setter) on a component's API surface it seems to not always work like it should. The first problem -- which you can see here -- is that when the value passed back from the setter is different from the value passed in (e.g., a boolean true is converted to a ES6 Set with a value of "true") you get a DEPRECATION warning which <i>may</i> end up being helpful in solving this problem. Note, that pressing the buttons which simply reflect back the same values work entirely as expected and without deprecation notice.
</p>
<p>
Play around with the buttons here to see the effect live in your very own browser.
</p>
{{my-component value=myProp}}
<hr>
<p>
CP returns the value passed in:
<button {{action "setValue" null}}>Set to NULL</button>
<button {{action "setValue" 'foobar'}}>Set to Foobar</button>
<button {{action "setValue" mySet}}>Set to a SET(one,two,three)</button>
</p>
<p>
CP manipulates the value passed in:
<button {{action "setValue" true}}>true -> Set(TRUE)</button>
<button {{action "setValue" false}}>false -> Set(FALSE)</button>
<button {{action "setValue" 'foo'}}>foo -> bar</button>
</p>
<hr>
<br>
<p>
Now let's move to <b>Stage 2</b> ... go to the <i>application.hbs</i> template and remove the display of the "myProp" from line 10. Now try playing with buttons and you'll find that the binding between application and component breaks down after the first call to the setter (post-initialisation). If you keep the inspector open you can see what IS and what IS NOT happening on the component side.
</p>
<br>
<span style='font-weight: 600'>Component</span><br/>
{{#if value.size}}
The value was turned into a Set:
<ul>
{{#each value as |item|}}
<li>{{item}}</li>
{{/each}}
</ul>
{{else}}
The value was: "{{value}}"
{{/if}}
{
"version": "0.4.0",
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.13.5/ember.js",
"ember-data": "https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.13.5/ember-data.js"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment