Skip to content

Instantly share code, notes, and snippets.

@runspired
Last active April 7, 2021 04:44
Show Gist options
  • Save runspired/de7fc96798d31969113cbb31074ec9cd to your computer and use it in GitHub Desktop.
Save runspired/de7fc96798d31969113cbb31074ec9cd to your computer and use it in GitHub Desktop.
Play with inverses
import Component from '@glimmer/component';
import Sort from '../state-object/sort';
export default class extends Component {
sorter = new Sort()
get sorted() {
const { data } = this.args;
const { sorter } = this;
sorter.data = data;
sorter.sortKey = 'title';
return sorter.sorted;
}
}
import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
}
import { helper } from '@ember/component/helper';
export default helper(function element(params, hash) {
let element = document.createElement(params[0]);
Object.assign(element, hash);
return element;
});
import { helper } from '@ember/component/helper';
const STATES = new WeakMap();
export function stateObjectFor(obj) {
let state = STATES.get(obj);
if (!state) {
state = Object.create(null);
state.cleanup = () => {
STATES.remove(obj);
};
STATES.set(obj, state);
}
return state;
}
export default helper(function localStateFor(params/*, hash*/) {
return stateObjectFor(params[0]);
});
import { helper } from '@ember/component/helper';
export default helper(function not(params/*, hash*/) {
return !params[0];
});
import { helper } from '@ember/component/helper';
const STATES = new WeakMap();
export function setStateFor(obj, value) {
STATES.set(obj, value);
}
export function stateObjectFor(obj) {
return STATES.get(obj)
}
export default helper(function stateObjectForHelper(params/*, hash*/) {
return stateObjectFor(params[0]);
});
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo } from 'ember-data/relationships';
export default class extends Model {
@attr title
@belongsTo('user', { async: false, inverse: null })
author;
}
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { hasMany } from 'ember-data/relationships';
import { setStateFor } from '../helpers/state-object-for';
import UserState from '../state-object/user';
export default class extends Model {
constructor() {
super(...arguments);
let state = new UserState();
setStateFor(this, state);
setStateFor(state, this);
}
@attr firstName
@attr lastName
@hasMany('post', { async: false, inverse: null })
posts
}
import Route from '@ember/routing/route';
const AUTHORS_PAYLOAD = {
data: [
{
type: 'user',
id: '2',
attributes: {
firstName: 'James',
lastName: 'Thoburn'
}
},
{
type: 'user',
id: '1',
attributes: {
firstName: 'Chris',
lastName: ''
},
relationships: {
posts: {
data: [
{ type: 'post', id: '1' },
{ type: 'post', id: '2' },
{ type: 'post', id: '3' },
{ type: 'post', id: '4' },
{ type: 'post', id: '5' }
]
}
}
},
]
};
const POSTS_PAYLOAD = {
data: [
{ type: 'post', id: '1', attributes: { title: 'first post' } },
{ type: 'post', id: '2', attributes: { title: 'second post' } },
{ type: 'post', id: '3', attributes: { title: 'third post' } },
{ type: 'post', id: '4', attributes: { title: 'four post' } },
{
type: 'post',
id: '5',
attributes: { title: 'five post' },
relationships: {
author: {
data: { type: 'user', id: '2' }
}
}
},
]
}
export default Route.extend({
model() {
const authors = this.store.push(AUTHORS_PAYLOAD);
const posts = this.store.push(POSTS_PAYLOAD);
return {
posts,
authors
}
}
});
import { tracked } from '@glimmer/tracking';
class Sort {
@tracked data;
@tracked sortKey;
@tracked filterFn = () => {};
get sorted() {
const { sortKey, filterFn } = this;
return this.data.filter(filterFn).sort((a, b) => {
return a[sortKey] > b[sortKey] ? -1 : 1;
});
}
}
import { stateObjectFor } from '../helpers/state-object-for';
export default class UserState {
get name() {
let state = stateObjectFor(this);
if (!state) {
return;
}
return state.firstName + ' ' + state.lastName;
}
}
<h1>Welcome to {{this.appName}}</h1>
<br>
<h2>Posts</h2>
{{#let (element 'h1' textContent="hi") (element 'div') as |h1 div|}}
{{#-in-element div}}
{{h1}}
{{/-in-element}}
<ul>
{{#each @model.posts as |post|}}
<li>{{post.title}} by {{get (state-object-for post.author) 'name'}}</li>
{{/each}}
</ul>
<h2>Posts by Author</h2>
{{#let (local-state-for this) as |c|}}
{{#if c.show}}
<ul>
{{#each @model.authors as |author|}}
{{#let (state-object-for author) as |state|}}
<li>{{state.name}}
<Input @value={{author.lastName}} />
<ul>
{{#each author.posts as |post|}}
<li>
{{#let (local-state-for post) as |local|}}
<Input type="checkbox" @value={{local.checked}} /> Is Awesome {{if local.checked 'yes' 'no'}}
{{/let}}
{{post.title}}
</li>
{{/each}}
</ul>
</li>
{{/let}}
{{/each}}
</ul>
{{/if}}
<button {{on "click" (fn (mut c.show) (not c.show))}}>Toggle</button>
{{div}}
{{/let}}
{{/let}}
<br>
<br>
{{outlet}}
<br>
<br>
<ul>
{{#each this.sorted as |post|}}
<li>{{post.title}}</li>
{{/each}}
</ul>
{
"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