Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jasonmit/b1c411224de5a9ab6bb3757d1acac8c8 to your computer and use it in GitHub Desktop.
Save jasonmit/b1c411224de5a9ab6bb3757d1acac8c8 to your computer and use it in GitHub Desktop.
WeakMap and the KVO
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
init() {
this._super(...arguments);
this.objects = [
{ label: 'First' },
{ label: 'Second' }
];
this.errors = new WeakMap();
this.errors.set(this.objects[0], { message: 'Danger, Will Robinson!' });
},
actions: {
createError() {
const second = this.objects[1];
this.errors.set(second, {
message: 'Now I\'m in danger, too!'
});
this.notifyPropertyChange('errors');
}
}
});
import Ember from 'ember';
export function weakmapGet([weakMap, key]) {
return weakMap.get(key);
}
export default Ember.Helper.helper(weakmapGet);
<h1>Binding to Changes in a WeakMap</h1>
<p>Click the below button to update the <code>WeakMap</code></p>
<hr />
<p>In the first example, when adding to a <code>WeakMap</code>, the new value appears because we manually use <code>notifyPropertyChange</code>. This works because we're relying on the changes to <code>errors</code> within the same context as the owner of the property.</p>
{{#each objects as |obj|}}
{{render-object
object=obj
error=(weakmap-get errors obj)
}}
{{/each}}
<p>However, in the second example we pass the <code>errors</code> object as a property, and the component is not made aware of the changes. The same objects are being used, but the DOM has the previous state.</p>
{{indirectly-render-objects
objects=objects
errors=errors
}}
<br />
<button {{action 'createError'}}>
Create the second error
</button>
{{#each objects as |obj|}}
{{render-object
object=obj
error=(weakmap-get errors obj)
}}
{{/each}}
{{object.label}}: {{if error error.message 'All clear!'}}
{
"version": "0.15.0",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.2.2",
"ember-template-compiler": "3.2.2",
"ember-testing": "3.2.2"
},
"addons": {
"ember-data": "3.2.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment