-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathattr.js
132 lines (111 loc) · 3.62 KB
/
attr.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import Ember from 'ember';
import { deprecate } from "ember-data/-private/debug";
/**
@module ember-data
*/
function getDefaultValue(record, options, key) {
if (typeof options.defaultValue === "function") {
return options.defaultValue.apply(null, arguments);
} else {
let defaultValue = options.defaultValue;
deprecate(`Non primitive defaultValues are deprecated because they are shared between all instances. If you would like to use a complex object as a default value please provide a function that returns the complex object.`,
typeof defaultValue !== 'object' || defaultValue === null, {
id: 'ds.defaultValue.complex-object',
until: '3.0.0'
});
return defaultValue;
}
}
function hasValue(record, key) {
return key in record._attributes ||
key in record._inFlightAttributes ||
key in record._data;
}
function getValue(record, key) {
if (key in record._attributes) {
return record._attributes[key];
} else if (key in record._inFlightAttributes) {
return record._inFlightAttributes[key];
} else {
return record._data[key];
}
}
/**
`DS.attr` defines an attribute on a [DS.Model](/api/data/classes/DS.Model.html).
By default, attributes are passed through as-is, however you can specify an
optional type to have the value automatically transformed.
Ember Data ships with four basic transform types: `string`, `number`,
`boolean` and `date`. You can define your own transforms by subclassing
[DS.Transform](/api/data/classes/DS.Transform.html).
Note that you cannot use `attr` to define an attribute of `id`.
`DS.attr` takes an optional hash as a second parameter, currently
supported options are:
- `defaultValue`: Pass a string or a function to be called to set the attribute
to a default value if none is supplied.
Example
```app/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr('string'),
email: DS.attr('string'),
verified: DS.attr('boolean', { defaultValue: false })
});
```
Default value can also be a function. This is useful it you want to return
a new object for each attribute.
```app/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
username: attr('string'),
email: attr('string'),
settings: attr({defaultValue: function() {
return {};
}})
});
```
@namespace
@method attr
@for DS
@param {String} type the attribute type
@param {Object} options a hash of options
@return {Attribute}
*/
export default function attr(type, options) {
if (typeof type === 'object') {
options = type;
type = undefined;
} else {
options = options || {};
}
var meta = {
type: type,
isAttribute: true,
options: options
};
return Ember.computed({
get(key) {
var internalModel = this._internalModel;
if (hasValue(internalModel, key)) {
return getValue(internalModel, key);
} else {
return getDefaultValue(this, options, key);
}
},
set(key, value) {
var internalModel = this._internalModel;
var oldValue = getValue(internalModel, key);
if (value !== oldValue) {
// Add the new value to the changed attributes hash; it will get deleted by
// the 'didSetProperty' handler if it is no different from the original value
internalModel._attributes[key] = value;
this._internalModel.send('didSetProperty', {
name: key,
oldValue: oldValue,
originalValue: internalModel._data[key],
value: value
});
}
return value;
}
}).meta(meta);
}