Skip to content

Instantly share code, notes, and snippets.

@bryanaka
Forked from runspired/controllers.application.js
Last active February 5, 2017 07:02
Show Gist options
  • Save bryanaka/d6902e247dec459d314eda1ec9199995 to your computer and use it in GitHub Desktop.
Save bryanaka/d6902e247dec459d314eda1ec9199995 to your computer and use it in GitHub Desktop.
Complex Attrs - decorator version
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
trueModel: Ember.computed(function() {
return this.get('store').peekRecord('my-model', '123');
}),
actions: {
changeValue() {
let model = this.get('trueModel');
let enumerable = model.get('myEnum');
model.set('myEnum', enumerable.value === 'A' ? 'B' : 'A');
debugger;
}
},
init() {
this._super();
this.get('store').pushPayload({
data: {
type: 'my-model',
id: '123',
attributes: {
'my-enum': 'A'
}
}
});
}
});
import Model from "ember-data/model";
import Enum from '../utils/enum';
import decoratedAttr from '../utils/complex-attr';
import { belongsTo, hasMany } from "ember-data/relationships";
export const ENUM_OPTIONS = ['A', 'B', 'C', 'D'];
export default Model.extend({
myEnum: decoratedAttr('enum', {
decorator: Enum,
options: ENUM_OPTIONS,
defaultValue: function() { return ENUM_OPTIONS[0]; }
})
});
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{outlet}}
<b>My Enum is:</b> {{trueModel.myEnum}} <br><br>
<b>Is it A?</b> {{if trueModel.myEnum.isA 'Yes' 'No'}} <br>
<b>Is it B?</b> {{if trueModel.myEnum.isB 'Yes' 'No'}} <br>
<b>Is the model dirty?</b> {{if trueModel.hasDirtyAttributes 'Yes' 'No'}} <br>
<button {{action "changeValue"}}>Change The Enum</button>
<br>
<br>
import Transform from 'ember-data/transform';
export default Transform.extend({
deserialize(v) { return v; },
serialize(v) { return v; }
});
{
"version": "0.11.0",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.10.2",
"ember-data": "2.11.0",
"ember-template-compiler": "2.10.2",
"ember-testing": "2.10.2"
},
"addons": {}
}
import Ember from 'ember';
import DS from 'ember-data';
const { computed, meta, cacheFor } = Ember;
const { attr } = DS;
export default function complexAttr(type, options) {
let dsAttr = attr(type, options);
let decoratorClass = options.decorator;
let decorator = new decoratorClass(options);
return computed({
get(key) {
var value = dsAttr.get(this, key);
decorator.decorate(value);
return decorator;
},
set(key, value) {
var oldValue = dsAttr.get(this, key);
if (oldValue === value) { return decorator; }
value = dsAttr.set(this, key, value);
decorator.decorate(value);
var cache = meta(this).writableCache();
cacheFor.set(cache, key, decorator);
return decorator;
}
}).meta(dsAttr._meta);
}
function assert(msg, test) {
if (!test) {
console.error(msg);
debugger;
}
}
function capitalize(s) {
return s.substr(0, 1).toUpperCase() + s.substr(1);
}
export default class Enum {
constructor(options) {
this.options = options.options;
this.defaultValue = options.defaultValue;
}
setUnknownProperty(key, value) {
throw new Error('illegal attempt to set a property on an Enum');
}
unknownProperty(key) {
let options = this.options;
let option = key.toUpperCase().substr(2);
assert(
`You passed the invalid isOption flag '${key}' to the ENUM: [${options.join(', ')}]`,
options.includes(option)
);
return this._data === option;
}
get value() {
return this._data;
}
set value(newValue) {
var isValidValue = this.options.includes(newValue);
assert(
`You passed the invalid isOption flag '${newValue}' to the ENUM: [${this.options.join(', ')}]`,
isValidValue);
return this._data = newValue;
}
decorate(normalValue) {
if (this.value !== normalValue) {
this.value = normalValue;
}
return this;
}
valueOf() {
return this._data;
}
toString() {
return this.value;
}
toJSON() {
let value = this.value;
let shape = {
value
};
let opts = this.options;
for (let i = 0, j = opts.length; i < j; i++) {
let key = opts[i];
shape[`is${capitalize(key)}`] = value === key;
}
return shape;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment