Complex Attrs
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'); | |
} | |
}, | |
init() { | |
this._super(); | |
this.get('store').pushPayload({ | |
data: { | |
type: 'my-model', | |
id: '123', | |
attributes: { | |
'my-enum': 'A' | |
} | |
} | |
}); | |
} | |
}); |
import Model from "ember-data/model"; | |
import attr from '../utils/complex-attr'; | |
import { belongsTo, hasMany } from "ember-data/relationships"; | |
export const ENUM_OPTIONS = ['A', 'B', 'C', 'D']; | |
export default Model.extend({ | |
myEnum: attr('enum', { | |
options: ENUM_OPTIONS, | |
defaultValue: function() { return ENUM_OPTIONS[0]; } | |
}) | |
}); |
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 Enum from './enum'; | |
export default function complexAttr(type, options) { | |
let meta = { | |
type: type, | |
isAttribute: true, | |
options: options | |
}; | |
const enumerable = new Enum(options.options, options.defaultValue); | |
return Ember.computed({ | |
get(key) { | |
enumerable.__meta.key = key; | |
enumerable.__meta._internalModel = this._internalModel; | |
return enumerable; | |
}, | |
set(key, value) { | |
var internalModel = this._internalModel; | |
var oldValue = enumerable.value; | |
var originalValue; | |
if (value !== oldValue) { | |
internalModel._attributes[key] = value; | |
if (key in internalModel._inFlightAttributes) { | |
originalValue = internalModel._inFlightAttributes[key]; | |
} else { | |
originalValue = internalModel._data[key].value; | |
} | |
this._internalModel.send('didSetProperty', { | |
name: key, | |
oldValue: oldValue, | |
originalValue: originalValue, | |
value: value | |
}); | |
this.notifyPropertyChange(key); | |
} | |
return enumerable; | |
} | |
}).meta(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, defaultValueFn) { | |
this.__meta = { | |
_internalModel: null, | |
key: '', | |
options, | |
defaultValue: null, | |
defaultValueFn | |
}; | |
} | |
setUnknownProperty(key, value) { | |
throw new Error('illegal attempt to set a property on an Enum'); | |
} | |
unknownProperty(key) { | |
let options = this.__meta.options; | |
let option = key.toUpperCase().substr(2); | |
assert( | |
`You passed the invalid isOption flag '${key}' to the ENUM: [${options.join(', ')}]`, | |
options.contains(option) | |
); | |
return this.value === option; | |
} | |
get value() { | |
let meta = this.__meta; | |
let key = meta.key; | |
let internalModel = meta._internalModel; | |
return internalModel._attributes[key] || | |
internalModel._inFlightAttributes[key] || | |
internalModel._data[key] || | |
meta.defaultValue || | |
(meta.defaultValue = meta.defaultValueFn()); | |
} | |
set value(option) { | |
assert( | |
`You passed an invalid option value '${option}' to the ENUM: [${options.join(', ')}]`, | |
this.__meta.options.contains(option) | |
); | |
this.__meta.currentState = option; | |
} | |
valueOf() { | |
return this.value; | |
} | |
toString() { | |
return this.value; | |
} | |
toJSON() { | |
let meta = this.__meta; | |
let value = this.value; | |
let shape = { | |
value | |
}; | |
let opts = meta.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