Skip to content

Instantly share code, notes, and snippets.

@lifeart
Last active January 30, 2021 09:17
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 lifeart/9b532661dd0ff3b4062829fb82df496b to your computer and use it in GitHub Desktop.
Save lifeart/9b532661dd0ff3b4062829fb82df496b to your computer and use it in GitHub Desktop.
Immutable Ember Data
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class ApplicationController extends Controller {
@service('store') store;
constructor() {
super(...arguments);
const initial = this.store.createRecord('immutablel', { props: { name: 'Jake' }});
}
@tracked cursor = null;
get currentCursor() {
return this.cursor === null ? this.models.length : this.cursor;
}
get models() {
return this.store.peekAll('immutablel');
}
get latest() {
if (this.cursor !== null) {
return this.models.findBy('cursor', this.cursor);
}
return this.models.firstObject.latest;
}
@action
setCursor(e) {
let value = parseInt(e.target.value, 10);
if (this.models.length === value) {
value = null;
}
this.cursor = value;
}
}
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo } from 'ember-data/relationships';
export default class extends Model {
@belongsTo('immutablel', { inverse: 'child', async: false }) parent;
@belongsTo('immutablel', { inverse: 'parent', async: false }) child;
cursor = 1;
get latest() {
let item = this;
while (item.child) {
item = item.child;
}
return item;
}
get name() {
return this.props.name;
}
set name(value) {
if (this !== this.latest) {
this.latest.name = value;
return;
}
this._fork('name', value);
}
_fork(key, value) {
this.store.createRecord('immutablel', {
parent: this,
cursor: this.cursor + 1,
props: { ...this.props, [key]: value }
});
}
@attr({ defaultValue() { return { name: ''} }}) props;
}
States count: {{this.models.length}}<br><br>
Latest state:<br> <Input @value={{this.latest.name}} /><br><br>
<br>
<label>State control, cursor {{this.currentCursor}} </label><br>
(1) <input type="range" min="1" value={{this.currentCursor}} max={{this.models.length}} {{on 'input' this.setCursor}} > ({{this.models.length}})
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "3.18.1",
"ember-template-compiler": "3.18.1",
"ember-testing": "3.18.1"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-data": "3.18.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment