@ember-data/model 5.6.0-alpha.2 → 5.6.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/-private.js +1 -2
- package/dist/-private.js.map +1 -1
- package/dist/{model-Dkk-TZlL.js → errors-DsUSZ9m8.js} +41 -2335
- package/dist/errors-DsUSZ9m8.js.map +1 -0
- package/dist/{hooks-o1U_cEA3.js → hooks-rXIjX2-H.js} +1 -2
- package/dist/{hooks-o1U_cEA3.js.map → hooks-rXIjX2-H.js.map} +1 -1
- package/dist/hooks.js +2 -2
- package/dist/index.js +667 -5
- package/dist/index.js.map +1 -1
- package/dist/migration-support.js +7 -14
- package/dist/migration-support.js.map +1 -1
- package/dist/schema-provider-B6-5uzxP.js +2229 -0
- package/dist/schema-provider-B6-5uzxP.js.map +1 -0
- package/package.json +16 -19
- package/unstable-preview-types/-private/attr.d.ts +4 -12
- package/unstable-preview-types/-private/attr.d.ts.map +1 -1
- package/unstable-preview-types/-private/belongs-to.d.ts +0 -6
- package/unstable-preview-types/-private/belongs-to.d.ts.map +1 -1
- package/unstable-preview-types/-private/errors.d.ts +4 -15
- package/unstable-preview-types/-private/errors.d.ts.map +1 -1
- package/unstable-preview-types/-private/has-many.d.ts +0 -3
- package/unstable-preview-types/-private/has-many.d.ts.map +1 -1
- package/unstable-preview-types/-private/model.d.ts +531 -562
- package/unstable-preview-types/-private/model.d.ts.map +1 -1
- package/unstable-preview-types/-private/promise-belongs-to.d.ts +0 -4
- package/unstable-preview-types/-private/promise-belongs-to.d.ts.map +1 -1
- package/unstable-preview-types/-private/promise-many-array.d.ts +3 -11
- package/unstable-preview-types/-private/promise-many-array.d.ts.map +1 -1
- package/unstable-preview-types/-private/references/belongs-to.d.ts +3 -12
- package/unstable-preview-types/-private/references/belongs-to.d.ts.map +1 -1
- package/unstable-preview-types/-private/references/has-many.d.ts +7 -19
- package/unstable-preview-types/-private/references/has-many.d.ts.map +1 -1
- package/unstable-preview-types/-private/type-utils.d.ts +0 -5
- package/unstable-preview-types/-private/type-utils.d.ts.map +1 -1
- package/unstable-preview-types/-private.d.ts +0 -4
- package/unstable-preview-types/-private.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +23 -20
- package/unstable-preview-types/index.d.ts.map +1 -1
- package/unstable-preview-types/migration-support.d.ts +4 -10
- package/unstable-preview-types/migration-support.d.ts.map +1 -1
- package/dist/has-many-BXU96bZ9.js +0 -682
- package/dist/has-many-BXU96bZ9.js.map +0 -1
- package/dist/model-Dkk-TZlL.js.map +0 -1
- package/dist/schema-provider-DyG6fJXt.js +0 -259
- package/dist/schema-provider-DyG6fJXt.js.map +0 -1
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
declare module '@ember-data/model/-private/model' {
|
|
2
|
-
/**
|
|
3
|
-
@module @ember-data/model
|
|
4
|
-
*/
|
|
5
2
|
import EmberObject from '@ember/object';
|
|
6
3
|
import type { Snapshot } from '@ember-data/legacy-compat/-private';
|
|
7
4
|
import type Store from '@ember-data/store';
|
|
@@ -35,392 +32,309 @@ declare module '@ember-data/model/-private/model' {
|
|
|
35
32
|
_modelFactoryCache: FactoryCache;
|
|
36
33
|
};
|
|
37
34
|
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```js
|
|
41
|
-
import Model, { attr } from '@ember-data/model';
|
|
42
|
-
|
|
43
|
-
export default class User extends Model {
|
|
44
|
-
@attr name;
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Models are used both to define the static schema for a
|
|
49
|
-
particular resource type as well as the class to instantiate
|
|
50
|
-
to present that data from cache.
|
|
51
|
-
|
|
52
|
-
@class Model
|
|
53
|
-
@public
|
|
54
|
-
@extends Ember.EmberObject
|
|
55
|
-
*/
|
|
35
|
+
* @noInheritDoc
|
|
36
|
+
*/
|
|
56
37
|
interface Model {
|
|
57
|
-
serialize<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): unknown;
|
|
58
|
-
destroyRecord<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<this>;
|
|
59
|
-
unloadRecord<T extends MinimalLegacyRecord>(this: T): void;
|
|
60
|
-
changedAttributes<T extends MinimalLegacyRecord>(this: T): ChangedAttributesHash;
|
|
61
|
-
rollbackAttributes<T extends MinimalLegacyRecord>(this: T): void;
|
|
62
|
-
_createSnapshot<T extends MinimalLegacyRecord>(this: T): Snapshot<T>;
|
|
63
|
-
save<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<this>;
|
|
64
|
-
reload<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<T>;
|
|
65
|
-
belongsTo<T extends Model, K extends keyof T & string>(this: T, prop: K & (K extends _MaybeBelongsToFields<T> ? K : never)): BelongsToReference<T, K>;
|
|
66
|
-
hasMany<T extends MinimalLegacyRecord, K extends MaybeHasManyFields<T>>(this: T, prop: K): HasManyReference<T, K>;
|
|
67
|
-
deleteRecord<T extends MinimalLegacyRecord>(this: T): void;
|
|
68
|
-
}
|
|
69
|
-
class Model extends EmberObject implements MinimalLegacyRecord {
|
|
70
|
-
store: Store;
|
|
71
|
-
___recordState: RecordState;
|
|
72
|
-
___private_notifications: object;
|
|
73
|
-
[RecordStore]: Store;
|
|
74
|
-
init(options: ModelCreateArgs): void;
|
|
75
|
-
destroy(): this;
|
|
76
38
|
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
been created. Most records created by the store will quickly
|
|
80
|
-
transition to the `loading` state if data needs to be fetched from
|
|
81
|
-
the server or the `created` state if the record is created on the
|
|
82
|
-
client. A record can also enter the empty state if the adapter is
|
|
83
|
-
unable to locate the record.
|
|
39
|
+
Create a JSON representation of the record, using the serialization
|
|
40
|
+
strategy of the store's adapter.
|
|
84
41
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
get isEmpty(): boolean;
|
|
91
|
-
/**
|
|
92
|
-
If this property is `true` the record is in the `loading` state. A
|
|
93
|
-
record enters this state when the store asks the adapter for its
|
|
94
|
-
data. It remains in this state until the adapter provides the
|
|
95
|
-
requested data.
|
|
42
|
+
`serialize` takes an optional hash as a parameter, currently
|
|
43
|
+
supported options are:
|
|
44
|
+
|
|
45
|
+
- `includeId`: `true` if the record's ID should be included in the
|
|
46
|
+
JSON representation.
|
|
96
47
|
|
|
97
|
-
@property isLoading
|
|
98
48
|
@public
|
|
99
|
-
@
|
|
100
|
-
@
|
|
49
|
+
@param {Object} options
|
|
50
|
+
@return {Object} an object whose values are primitive JSON values only
|
|
101
51
|
*/
|
|
102
|
-
|
|
52
|
+
serialize<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): unknown;
|
|
103
53
|
/**
|
|
104
|
-
|
|
105
|
-
record enters this state when its data is populated. Most of a
|
|
106
|
-
record's lifecycle is spent inside substates of the `loaded`
|
|
107
|
-
state.
|
|
54
|
+
Same as `deleteRecord`, but saves the record immediately.
|
|
108
55
|
|
|
109
56
|
Example
|
|
110
57
|
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
record.isLoaded; // true
|
|
58
|
+
```js
|
|
59
|
+
import Component from '@glimmer/component';
|
|
114
60
|
|
|
115
|
-
|
|
116
|
-
|
|
61
|
+
export default class extends Component {
|
|
62
|
+
delete = () => {
|
|
63
|
+
this.args.model.destroyRecord().then(function() {
|
|
64
|
+
this.transitionToRoute('model.index');
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
117
68
|
```
|
|
118
69
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@type {Boolean}
|
|
122
|
-
@readOnly
|
|
123
|
-
*/
|
|
124
|
-
get isLoaded(): boolean;
|
|
125
|
-
/**
|
|
126
|
-
If this property is `true` the record is in the `dirty` state. The
|
|
127
|
-
record has local changes that have not yet been saved by the
|
|
128
|
-
adapter. This includes records that have been created (but not yet
|
|
129
|
-
saved) or deleted.
|
|
130
|
-
|
|
131
|
-
Example
|
|
70
|
+
If you pass an object on the `adapterOptions` property of the options
|
|
71
|
+
argument it will be passed to your adapter via the snapshot
|
|
132
72
|
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
|
|
73
|
+
```js
|
|
74
|
+
record.destroyRecord({ adapterOptions: { subscribe: false } });
|
|
75
|
+
```
|
|
136
76
|
|
|
137
|
-
|
|
77
|
+
```js [app/adapters/post.js]
|
|
78
|
+
import MyCustomAdapter from './custom-adapter';
|
|
138
79
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
80
|
+
export default class PostAdapter extends MyCustomAdapter {
|
|
81
|
+
deleteRecord(store, type, snapshot) {
|
|
82
|
+
if (snapshot.adapterOptions.subscribe) {
|
|
83
|
+
// ...
|
|
84
|
+
}
|
|
85
|
+
// ...
|
|
86
|
+
}
|
|
87
|
+
}
|
|
142
88
|
```
|
|
143
89
|
|
|
144
|
-
@since 1.13.0
|
|
145
|
-
@property hasDirtyAttributes
|
|
146
90
|
@public
|
|
147
|
-
@
|
|
148
|
-
@
|
|
91
|
+
@param {Object} options
|
|
92
|
+
@return {Promise} a promise that will be resolved when the adapter returns
|
|
93
|
+
successfully or rejected if the adapter returns with an error.
|
|
149
94
|
*/
|
|
150
|
-
|
|
95
|
+
destroyRecord<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<this>;
|
|
151
96
|
/**
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
adapter has not yet acknowledged that the changes have been
|
|
155
|
-
persisted to the backend.
|
|
156
|
-
|
|
157
|
-
Example
|
|
158
|
-
|
|
159
|
-
```javascript
|
|
160
|
-
let record = store.createRecord('model');
|
|
161
|
-
record.isSaving; // false
|
|
162
|
-
let promise = record.save();
|
|
163
|
-
record.isSaving; // true
|
|
164
|
-
promise.then(function() {
|
|
165
|
-
record.isSaving; // false
|
|
166
|
-
});
|
|
167
|
-
```
|
|
97
|
+
Unloads the record from the store. This will not send a delete request
|
|
98
|
+
to your server, it just unloads the record from memory.
|
|
168
99
|
|
|
169
|
-
@property isSaving
|
|
170
100
|
@public
|
|
171
|
-
@type {Boolean}
|
|
172
|
-
@readOnly
|
|
173
101
|
*/
|
|
174
|
-
|
|
102
|
+
unloadRecord<T extends MinimalLegacyRecord>(this: T): void;
|
|
175
103
|
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
104
|
+
Returns an object, whose keys are changed properties, and value is
|
|
105
|
+
an [oldProp, newProp] array.
|
|
106
|
+
|
|
107
|
+
The array represents the diff of the canonical state with the local state
|
|
108
|
+
of the model. Note: if the model is created locally, the canonical state is
|
|
109
|
+
empty since the adapter hasn't acknowledged the attributes yet:
|
|
182
110
|
|
|
183
111
|
Example
|
|
184
112
|
|
|
113
|
+
```js [app/models/mascot.js]
|
|
114
|
+
import Model, { attr } from '@ember-data/model';
|
|
115
|
+
|
|
116
|
+
export default class MascotModel extends Model {
|
|
117
|
+
@attr('string') name;
|
|
118
|
+
@attr('boolean', {
|
|
119
|
+
defaultValue: false
|
|
120
|
+
})
|
|
121
|
+
isAdmin;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
185
125
|
```javascript
|
|
186
|
-
let
|
|
187
|
-
record.isDeleted; // false
|
|
188
|
-
record.deleteRecord();
|
|
126
|
+
let mascot = store.createRecord('mascot');
|
|
189
127
|
|
|
190
|
-
//
|
|
191
|
-
record.isDeleted; // true
|
|
192
|
-
record.hasDirtyAttributes; // true
|
|
193
|
-
record.isSaving; // false
|
|
128
|
+
mascot.changedAttributes(); // {}
|
|
194
129
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
record.isDeleted; // true
|
|
198
|
-
record.isSaving; // true
|
|
130
|
+
mascot.set('name', 'Tomster');
|
|
131
|
+
mascot.changedAttributes(); // { name: [undefined, 'Tomster'] }
|
|
199
132
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
133
|
+
mascot.set('isAdmin', true);
|
|
134
|
+
mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
|
|
135
|
+
|
|
136
|
+
mascot.save().then(function() {
|
|
137
|
+
mascot.changedAttributes(); // {}
|
|
138
|
+
|
|
139
|
+
mascot.set('isAdmin', false);
|
|
140
|
+
mascot.changedAttributes(); // { isAdmin: [true, false] }
|
|
205
141
|
});
|
|
206
142
|
```
|
|
207
143
|
|
|
208
|
-
@property isDeleted
|
|
209
144
|
@public
|
|
210
|
-
@
|
|
211
|
-
|
|
145
|
+
@return {Object} an object, whose keys are changed properties,
|
|
146
|
+
and value is an [oldProp, newProp] array.
|
|
212
147
|
*/
|
|
213
|
-
|
|
148
|
+
changedAttributes<T extends MinimalLegacyRecord>(this: T): ChangedAttributesHash;
|
|
214
149
|
/**
|
|
215
|
-
If
|
|
216
|
-
|
|
217
|
-
client and the adapter has not yet report that it was successfully
|
|
218
|
-
saved.
|
|
150
|
+
If the model `hasDirtyAttributes` this function will discard any unsaved
|
|
151
|
+
changes. If the model `isNew` it will be removed from the store.
|
|
219
152
|
|
|
220
153
|
Example
|
|
221
154
|
|
|
222
155
|
```javascript
|
|
223
|
-
|
|
224
|
-
record.
|
|
225
|
-
|
|
226
|
-
record.
|
|
227
|
-
|
|
228
|
-
});
|
|
156
|
+
record.name; // 'Untitled Document'
|
|
157
|
+
record.set('name', 'Doc 1');
|
|
158
|
+
record.name; // 'Doc 1'
|
|
159
|
+
record.rollbackAttributes();
|
|
160
|
+
record.name; // 'Untitled Document'
|
|
229
161
|
```
|
|
230
162
|
|
|
231
|
-
@
|
|
163
|
+
@since 1.13.0
|
|
232
164
|
@public
|
|
233
|
-
@type {Boolean}
|
|
234
|
-
@readOnly
|
|
235
165
|
*/
|
|
236
|
-
|
|
166
|
+
rollbackAttributes<T extends MinimalLegacyRecord>(this: T): void;
|
|
237
167
|
/**
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
A record will be in the `valid` state when the adapter did not report any
|
|
241
|
-
server-side validation failures.
|
|
242
|
-
|
|
243
|
-
@property isValid
|
|
244
|
-
@public
|
|
245
|
-
@type {Boolean}
|
|
246
|
-
@readOnly
|
|
168
|
+
@private
|
|
247
169
|
*/
|
|
248
|
-
|
|
170
|
+
_createSnapshot<T extends MinimalLegacyRecord>(this: T): Snapshot<T>;
|
|
249
171
|
/**
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
state. Possible values are:
|
|
253
|
-
|
|
254
|
-
- `created` The record has been created by the client and not yet saved to the adapter.
|
|
255
|
-
- `updated` The record has been updated by the client and not yet saved to the adapter.
|
|
256
|
-
- `deleted` The record has been deleted by the client and not yet saved to the adapter.
|
|
172
|
+
Save the record and persist any changes to the record to an
|
|
173
|
+
external source via the adapter.
|
|
257
174
|
|
|
258
175
|
Example
|
|
259
176
|
|
|
260
177
|
```javascript
|
|
261
|
-
|
|
262
|
-
record.
|
|
178
|
+
record.set('name', 'Tomster');
|
|
179
|
+
record.save().then(function() {
|
|
180
|
+
// Success callback
|
|
181
|
+
}, function() {
|
|
182
|
+
// Error callback
|
|
183
|
+
});
|
|
263
184
|
```
|
|
264
185
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
@type {String}
|
|
268
|
-
@readOnly
|
|
269
|
-
*/
|
|
270
|
-
get dirtyType(): 'created' | 'updated' | 'deleted' | '';
|
|
271
|
-
/**
|
|
272
|
-
If `true` the adapter reported that it was unable to save local
|
|
273
|
-
changes to the backend for any reason other than a server-side
|
|
274
|
-
validation error.
|
|
275
|
-
|
|
276
|
-
Example
|
|
186
|
+
If you pass an object using the `adapterOptions` property of the options
|
|
187
|
+
argument it will be passed to your adapter via the snapshot.
|
|
277
188
|
|
|
278
|
-
```
|
|
279
|
-
record.
|
|
280
|
-
record.set('foo', 'valid value');
|
|
281
|
-
record.save().then(null, function() {
|
|
282
|
-
record.isError; // true
|
|
283
|
-
});
|
|
189
|
+
```js
|
|
190
|
+
record.save({ adapterOptions: { subscribe: false } });
|
|
284
191
|
```
|
|
285
192
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
@type {Boolean}
|
|
289
|
-
@readOnly
|
|
290
|
-
*/
|
|
291
|
-
get isError(): boolean;
|
|
292
|
-
set isError(v: boolean);
|
|
293
|
-
/**
|
|
294
|
-
If `true` the store is attempting to reload the record from the adapter.
|
|
295
|
-
|
|
296
|
-
Example
|
|
193
|
+
```js [app/adapters/post.js]
|
|
194
|
+
import MyCustomAdapter from './custom-adapter';
|
|
297
195
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
196
|
+
export default class PostAdapter extends MyCustomAdapter {
|
|
197
|
+
updateRecord(store, type, snapshot) {
|
|
198
|
+
if (snapshot.adapterOptions.subscribe) {
|
|
199
|
+
// ...
|
|
200
|
+
}
|
|
201
|
+
// ...
|
|
202
|
+
}
|
|
203
|
+
}
|
|
302
204
|
```
|
|
303
205
|
|
|
304
|
-
@property isReloading
|
|
305
206
|
@public
|
|
306
|
-
@
|
|
307
|
-
@
|
|
207
|
+
@param {Object} options
|
|
208
|
+
@return {Promise} a promise that will be resolved when the adapter returns
|
|
209
|
+
successfully or rejected if the adapter returns with an error.
|
|
308
210
|
*/
|
|
309
|
-
|
|
211
|
+
save<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<this>;
|
|
310
212
|
/**
|
|
311
|
-
|
|
312
|
-
managed by an external source. These are always coerced to be
|
|
313
|
-
strings before being used internally. Note when declaring the
|
|
314
|
-
attributes for a model it is an error to an id
|
|
315
|
-
attribute.
|
|
213
|
+
Reload the record from the adapter.
|
|
316
214
|
|
|
317
|
-
|
|
318
|
-
let record = store.createRecord('model');
|
|
319
|
-
record.id; // null
|
|
215
|
+
This will only work if the record has already finished loading.
|
|
320
216
|
|
|
321
|
-
|
|
322
|
-
|
|
217
|
+
Example
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
import Component from '@glimmer/component';
|
|
221
|
+
|
|
222
|
+
export default class extends Component {
|
|
223
|
+
async reload = () => {
|
|
224
|
+
await this.args.model.reload();
|
|
225
|
+
// do something with the reloaded model
|
|
226
|
+
}
|
|
227
|
+
}
|
|
323
228
|
```
|
|
324
229
|
|
|
325
|
-
@property id
|
|
326
230
|
@public
|
|
327
|
-
@
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
@property currentState
|
|
334
|
-
@private
|
|
335
|
-
@type {Object}
|
|
231
|
+
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter request
|
|
232
|
+
|
|
233
|
+
@return {Promise} a promise that will be resolved with the record when the
|
|
234
|
+
adapter returns successfully or rejected if the adapter returns
|
|
235
|
+
with an error.
|
|
336
236
|
*/
|
|
337
|
-
|
|
338
|
-
set currentState(_v: RecordState);
|
|
237
|
+
reload<T extends MinimalLegacyRecord>(this: T, options?: Record<string, unknown>): Promise<T>;
|
|
339
238
|
/**
|
|
340
|
-
|
|
239
|
+
Get the reference for the specified belongsTo relationship.
|
|
341
240
|
|
|
342
|
-
|
|
343
|
-
@public
|
|
344
|
-
*/
|
|
345
|
-
/**
|
|
346
|
-
When the record is in the `invalid` state this object will contain
|
|
347
|
-
any errors returned by the adapter. When present the errors hash
|
|
348
|
-
contains keys corresponding to the invalid property names
|
|
349
|
-
and values which are arrays of Javascript objects with two keys:
|
|
241
|
+
For instance, given the following model
|
|
350
242
|
|
|
351
|
-
-
|
|
352
|
-
|
|
243
|
+
```js [app/models/blog-post.js]
|
|
244
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
353
245
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
record.save().catch(function() {
|
|
358
|
-
record.errors.foo;
|
|
359
|
-
// [{message: 'foo should be a number.', attribute: 'foo'}]
|
|
360
|
-
});
|
|
246
|
+
export default class BlogPost extends Model {
|
|
247
|
+
@belongsTo('user', { async: true, inverse: null }) author;
|
|
248
|
+
}
|
|
361
249
|
```
|
|
362
250
|
|
|
363
|
-
|
|
364
|
-
|
|
251
|
+
Then the reference for the author relationship would be
|
|
252
|
+
retrieved from a record instance like so:
|
|
365
253
|
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
{{#each @model.errors.username as |error|}}
|
|
369
|
-
<div class="error">
|
|
370
|
-
{{error.message}}
|
|
371
|
-
</div>
|
|
372
|
-
{{/each}}
|
|
373
|
-
<label>Email: <Input @value={{@model.email}} /> </label>
|
|
374
|
-
{{#each @model.errors.email as |error|}}
|
|
375
|
-
<div class="error">
|
|
376
|
-
{{error.message}}
|
|
377
|
-
</div>
|
|
378
|
-
{{/each}}
|
|
254
|
+
```js
|
|
255
|
+
blogPost.belongsTo('author');
|
|
379
256
|
```
|
|
380
257
|
|
|
258
|
+
A `BelongsToReference` is a low-level API that allows access
|
|
259
|
+
and manipulation of a belongsTo relationship.
|
|
381
260
|
|
|
382
|
-
|
|
383
|
-
|
|
261
|
+
It is especially useful when you're dealing with `async` relationships
|
|
262
|
+
as it allows synchronous access to the relationship data if loaded, as
|
|
263
|
+
well as APIs for loading, reloading the data or accessing available
|
|
264
|
+
information without triggering a load.
|
|
384
265
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
{{message}}
|
|
389
|
-
</div>
|
|
390
|
-
{{/each}}
|
|
391
|
-
```
|
|
266
|
+
It may also be useful when using `sync` relationships that need to be
|
|
267
|
+
loaded/reloaded with more precise timing than marking the
|
|
268
|
+
relationship as `async` and relying on autofetch would have allowed.
|
|
392
269
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
270
|
+
However,keep in mind that marking a relationship as `async: false` will introduce
|
|
271
|
+
bugs into your application if the data is not always guaranteed to be available
|
|
272
|
+
by the time the relationship is accessed. Ergo, it is recommended when using this
|
|
273
|
+
approach to utilize `links` for unloaded relationship state instead of identifiers.
|
|
274
|
+
|
|
275
|
+
Reference APIs are entangled with the relationship's underlying state,
|
|
276
|
+
thus any getters or cached properties that utilize these will properly
|
|
277
|
+
invalidate if the relationship state changes.
|
|
278
|
+
|
|
279
|
+
References are "stable", meaning that multiple calls to retrieve the reference
|
|
280
|
+
for a given relationship will always return the same HasManyReference.
|
|
401
281
|
|
|
402
|
-
@property adapterError
|
|
403
282
|
@public
|
|
404
|
-
@
|
|
283
|
+
@param {String} name of the relationship
|
|
284
|
+
@since 2.5.0
|
|
285
|
+
@return {BelongsToReference} reference for this relationship
|
|
405
286
|
*/
|
|
406
|
-
|
|
407
|
-
set adapterError(v: unknown);
|
|
287
|
+
belongsTo<T extends Model, K extends keyof T & string>(this: T, prop: K & (K extends _MaybeBelongsToFields<T> ? K : never)): BelongsToReference<T, K>;
|
|
408
288
|
/**
|
|
409
|
-
|
|
410
|
-
strategy of the store's adapter.
|
|
289
|
+
Get the reference for the specified hasMany relationship.
|
|
411
290
|
|
|
412
|
-
|
|
413
|
-
supported options are:
|
|
291
|
+
For instance, given the following model
|
|
414
292
|
|
|
415
|
-
|
|
416
|
-
|
|
293
|
+
```js [app/models/blog-post.js]
|
|
294
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
295
|
+
|
|
296
|
+
export default class BlogPost extends Model {
|
|
297
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Then the reference for the comments relationship would be
|
|
302
|
+
retrieved from a record instance like so:
|
|
303
|
+
|
|
304
|
+
```js
|
|
305
|
+
blogPost.hasMany('comments');
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
A `HasManyReference` is a low-level API that allows access
|
|
309
|
+
and manipulation of a hasMany relationship.
|
|
310
|
+
|
|
311
|
+
It is especially useful when you are dealing with `async` relationships
|
|
312
|
+
as it allows synchronous access to the relationship data if loaded, as
|
|
313
|
+
well as APIs for loading, reloading the data or accessing available
|
|
314
|
+
information without triggering a load.
|
|
315
|
+
|
|
316
|
+
It may also be useful when using `sync` relationships with `@ember-data/model`
|
|
317
|
+
that need to be loaded/reloaded with more precise timing than marking the
|
|
318
|
+
relationship as `async` and relying on autofetch would have allowed.
|
|
319
|
+
|
|
320
|
+
However,keep in mind that marking a relationship as `async: false` will introduce
|
|
321
|
+
bugs into your application if the data is not always guaranteed to be available
|
|
322
|
+
by the time the relationship is accessed. Ergo, it is recommended when using this
|
|
323
|
+
approach to utilize `links` for unloaded relationship state instead of identifiers.
|
|
324
|
+
|
|
325
|
+
Reference APIs are entangled with the relationship's underlying state,
|
|
326
|
+
thus any getters or cached properties that utilize these will properly
|
|
327
|
+
invalidate if the relationship state changes.
|
|
328
|
+
|
|
329
|
+
References are "stable", meaning that multiple calls to retrieve the reference
|
|
330
|
+
for a given relationship will always return the same HasManyReference.
|
|
417
331
|
|
|
418
|
-
@method serialize
|
|
419
332
|
@public
|
|
420
|
-
@param {
|
|
421
|
-
@
|
|
333
|
+
@param {String} name of the relationship
|
|
334
|
+
@since 2.5.0
|
|
335
|
+
@return {HasManyReference} reference for this relationship
|
|
422
336
|
*/
|
|
423
|
-
|
|
337
|
+
hasMany<T extends MinimalLegacyRecord, K extends MaybeHasManyFields<T>>(this: T, prop: K): HasManyReference<T, K>;
|
|
424
338
|
/**
|
|
425
339
|
Marks the record as deleted but does not save it. You must call
|
|
426
340
|
`save` afterwards if you want to persist it. You might use this
|
|
@@ -447,295 +361,389 @@ declare module '@ember-data/model/-private/model' {
|
|
|
447
361
|
}
|
|
448
362
|
```
|
|
449
363
|
|
|
450
|
-
@method deleteRecord
|
|
451
364
|
@public
|
|
452
365
|
*/
|
|
366
|
+
deleteRecord<T extends MinimalLegacyRecord>(this: T): void;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Base class from which Models can be defined.
|
|
370
|
+
*
|
|
371
|
+
* ::: code-group
|
|
372
|
+
*
|
|
373
|
+
* ```js [app/models/user.js]
|
|
374
|
+
* import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
|
|
375
|
+
*
|
|
376
|
+
* export default class User extends Model {
|
|
377
|
+
* @attr name;
|
|
378
|
+
* @attr('number') age;
|
|
379
|
+
* @hasMany('post', { async: true, inverse: null }) posts;
|
|
380
|
+
* @belongsTo('group', { async: false, inverse: 'users' }) group;
|
|
381
|
+
* }
|
|
382
|
+
* ```
|
|
383
|
+
*
|
|
384
|
+
* ```ts [app/models/user.ts]
|
|
385
|
+
* import Model, { attr, belongsTo, hasMany, type AsyncHasMany } from '@ember-data/model';
|
|
386
|
+
* import type { NumberTransform } from '@ember-data/serializer/transform';
|
|
387
|
+
* import type Group from './group';
|
|
388
|
+
* import type Post from './post';
|
|
389
|
+
*
|
|
390
|
+
* export default class User extends Model {
|
|
391
|
+
* @attr name: string;
|
|
392
|
+
*
|
|
393
|
+
* @attr<NumberTransform>('number')
|
|
394
|
+
* age: number;
|
|
395
|
+
*
|
|
396
|
+
* @hasMany('post', { async: true, inverse: null })
|
|
397
|
+
* posts: AsyncHasMany<Post>;
|
|
398
|
+
*
|
|
399
|
+
* @belongsTo('group', { async: false, inverse: 'users' })
|
|
400
|
+
* group: Group | null;
|
|
401
|
+
* }
|
|
402
|
+
* ```
|
|
403
|
+
*
|
|
404
|
+
* :::
|
|
405
|
+
*
|
|
406
|
+
* Models both define the schema for a resource type and provide
|
|
407
|
+
* the class to use as the reactive object for data of resource
|
|
408
|
+
* of that type.
|
|
409
|
+
*
|
|
410
|
+
* @noInheritDoc
|
|
411
|
+
*/
|
|
412
|
+
class Model extends EmberObject implements MinimalLegacyRecord {
|
|
453
413
|
/**
|
|
454
|
-
|
|
414
|
+
* The store service instance which created this record instance
|
|
415
|
+
*/
|
|
416
|
+
store: Store;
|
|
417
|
+
/** @internal */
|
|
418
|
+
___recordState: RecordState;
|
|
419
|
+
/** @internal */
|
|
420
|
+
___private_notifications: object;
|
|
421
|
+
/** @internal */
|
|
422
|
+
[RecordStore]: Store;
|
|
423
|
+
/** @internal */
|
|
424
|
+
init(options: ModelCreateArgs): void;
|
|
425
|
+
/** @internal */
|
|
426
|
+
destroy(): this;
|
|
427
|
+
/**
|
|
428
|
+
If this property is `true` the record is in the `empty`
|
|
429
|
+
state. Empty is the first state all records enter after they have
|
|
430
|
+
been created. Most records created by the store will quickly
|
|
431
|
+
transition to the `loading` state if data needs to be fetched from
|
|
432
|
+
the server or the `created` state if the record is created on the
|
|
433
|
+
client. A record can also enter the empty state if the adapter is
|
|
434
|
+
unable to locate the record.
|
|
435
|
+
|
|
436
|
+
@property isEmpty
|
|
437
|
+
@public
|
|
438
|
+
@readonly
|
|
439
|
+
*/
|
|
440
|
+
get isEmpty(): boolean;
|
|
441
|
+
/**
|
|
442
|
+
If this property is `true` the record is in the `loading` state. A
|
|
443
|
+
record enters this state when the store asks the adapter for its
|
|
444
|
+
data. It remains in this state until the adapter provides the
|
|
445
|
+
requested data.
|
|
446
|
+
|
|
447
|
+
@property isLoading
|
|
448
|
+
@public
|
|
449
|
+
@readonly
|
|
450
|
+
*/
|
|
451
|
+
get isLoading(): boolean;
|
|
452
|
+
/**
|
|
453
|
+
If this property is `true` the record is in the `loaded` state. A
|
|
454
|
+
record enters this state when its data is populated. Most of a
|
|
455
|
+
record's lifecycle is spent inside substates of the `loaded`
|
|
456
|
+
state.
|
|
455
457
|
|
|
456
458
|
Example
|
|
457
459
|
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
+
```javascript
|
|
461
|
+
let record = store.createRecord('model');
|
|
462
|
+
record.isLoaded; // true
|
|
460
463
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
this.args.model.destroyRecord().then(function() {
|
|
464
|
-
this.transitionToRoute('model.index');
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
}
|
|
464
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
465
|
+
model.isLoaded;
|
|
468
466
|
```
|
|
469
467
|
|
|
470
|
-
|
|
471
|
-
|
|
468
|
+
@property isLoaded
|
|
469
|
+
@public
|
|
470
|
+
@readonly
|
|
471
|
+
*/
|
|
472
|
+
get isLoaded(): boolean;
|
|
473
|
+
/**
|
|
474
|
+
If this property is `true` the record is in the `dirty` state. The
|
|
475
|
+
record has local changes that have not yet been saved by the
|
|
476
|
+
adapter. This includes records that have been created (but not yet
|
|
477
|
+
saved) or deleted.
|
|
472
478
|
|
|
473
|
-
|
|
474
|
-
record.destroyRecord({ adapterOptions: { subscribe: false } });
|
|
475
|
-
```
|
|
479
|
+
Example
|
|
476
480
|
|
|
477
|
-
```
|
|
478
|
-
|
|
481
|
+
```javascript
|
|
482
|
+
let record = store.createRecord('model');
|
|
483
|
+
record.hasDirtyAttributes; // true
|
|
479
484
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
// ...
|
|
486
|
-
}
|
|
487
|
-
}
|
|
485
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
486
|
+
|
|
487
|
+
model.hasDirtyAttributes; // false
|
|
488
|
+
model.foo = 'some value';
|
|
489
|
+
model.hasDirtyAttributes; // true
|
|
488
490
|
```
|
|
489
491
|
|
|
490
|
-
@
|
|
492
|
+
@since 1.13.0
|
|
493
|
+
@property hasDirtyAttributes
|
|
491
494
|
@public
|
|
492
|
-
@
|
|
493
|
-
@return {Promise} a promise that will be resolved when the adapter returns
|
|
494
|
-
successfully or rejected if the adapter returns with an error.
|
|
495
|
+
@readonly
|
|
495
496
|
*/
|
|
497
|
+
get hasDirtyAttributes(): boolean;
|
|
496
498
|
/**
|
|
497
|
-
|
|
498
|
-
|
|
499
|
+
If this property is `true` the record is in the `saving` state. A
|
|
500
|
+
record enters the saving state when `save` is called, but the
|
|
501
|
+
adapter has not yet acknowledged that the changes have been
|
|
502
|
+
persisted to the backend.
|
|
503
|
+
|
|
504
|
+
Example
|
|
499
505
|
|
|
500
|
-
|
|
506
|
+
```javascript
|
|
507
|
+
let record = store.createRecord('model');
|
|
508
|
+
record.isSaving; // false
|
|
509
|
+
let promise = record.save();
|
|
510
|
+
record.isSaving; // true
|
|
511
|
+
promise.then(function() {
|
|
512
|
+
record.isSaving; // false
|
|
513
|
+
});
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
@property isSaving
|
|
501
517
|
@public
|
|
518
|
+
@readonly
|
|
502
519
|
*/
|
|
520
|
+
get isSaving(): boolean;
|
|
503
521
|
/**
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
522
|
+
If this property is `true` the record is in the `deleted` state
|
|
523
|
+
and has been marked for deletion. When `isDeleted` is true and
|
|
524
|
+
`hasDirtyAttributes` is true, the record is deleted locally but the deletion
|
|
525
|
+
was not yet persisted. When `isSaving` is true, the change is
|
|
526
|
+
in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the
|
|
527
|
+
change has persisted.
|
|
510
528
|
|
|
511
529
|
Example
|
|
512
530
|
|
|
513
|
-
```
|
|
514
|
-
|
|
531
|
+
```javascript
|
|
532
|
+
let record = store.createRecord('model');
|
|
533
|
+
record.isDeleted; // false
|
|
534
|
+
record.deleteRecord();
|
|
515
535
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
})
|
|
521
|
-
isAdmin;
|
|
522
|
-
}
|
|
523
|
-
```
|
|
536
|
+
// Locally deleted
|
|
537
|
+
record.isDeleted; // true
|
|
538
|
+
record.hasDirtyAttributes; // true
|
|
539
|
+
record.isSaving; // false
|
|
524
540
|
|
|
525
|
-
|
|
526
|
-
let
|
|
541
|
+
// Persisting the deletion
|
|
542
|
+
let promise = record.save();
|
|
543
|
+
record.isDeleted; // true
|
|
544
|
+
record.isSaving; // true
|
|
527
545
|
|
|
528
|
-
|
|
546
|
+
// Deletion Persisted
|
|
547
|
+
promise.then(function() {
|
|
548
|
+
record.isDeleted; // true
|
|
549
|
+
record.isSaving; // false
|
|
550
|
+
record.hasDirtyAttributes; // false
|
|
551
|
+
});
|
|
552
|
+
```
|
|
529
553
|
|
|
530
|
-
|
|
531
|
-
|
|
554
|
+
@property isDeleted
|
|
555
|
+
@public
|
|
556
|
+
@readonly
|
|
557
|
+
*/
|
|
558
|
+
get isDeleted(): boolean;
|
|
559
|
+
/**
|
|
560
|
+
If this property is `true` the record is in the `new` state. A
|
|
561
|
+
record will be in the `new` state when it has been created on the
|
|
562
|
+
client and the adapter has not yet report that it was successfully
|
|
563
|
+
saved.
|
|
532
564
|
|
|
533
|
-
|
|
534
|
-
mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
|
|
565
|
+
Example
|
|
535
566
|
|
|
536
|
-
|
|
537
|
-
|
|
567
|
+
```javascript
|
|
568
|
+
let record = store.createRecord('model');
|
|
569
|
+
record.isNew; // true
|
|
538
570
|
|
|
539
|
-
|
|
540
|
-
|
|
571
|
+
record.save().then(function(model) {
|
|
572
|
+
model.isNew; // false
|
|
541
573
|
});
|
|
542
574
|
```
|
|
543
575
|
|
|
544
|
-
@
|
|
576
|
+
@property isNew
|
|
577
|
+
@public
|
|
578
|
+
@readonly
|
|
579
|
+
*/
|
|
580
|
+
get isNew(): boolean;
|
|
581
|
+
/**
|
|
582
|
+
If this property is `true` the record is in the `valid` state.
|
|
583
|
+
|
|
584
|
+
A record will be in the `valid` state when the adapter did not report any
|
|
585
|
+
server-side validation failures.
|
|
586
|
+
|
|
587
|
+
@property isValid
|
|
545
588
|
@public
|
|
546
|
-
@
|
|
547
|
-
and value is an [oldProp, newProp] array.
|
|
589
|
+
@readonly
|
|
548
590
|
*/
|
|
591
|
+
get isValid(): boolean;
|
|
549
592
|
/**
|
|
550
|
-
If the
|
|
551
|
-
|
|
593
|
+
If the record is in the dirty state this property will report what
|
|
594
|
+
kind of change has caused it to move into the dirty
|
|
595
|
+
state. Possible values are:
|
|
596
|
+
|
|
597
|
+
- `created` The record has been created by the client and not yet saved to the adapter.
|
|
598
|
+
- `updated` The record has been updated by the client and not yet saved to the adapter.
|
|
599
|
+
- `deleted` The record has been deleted by the client and not yet saved to the adapter.
|
|
552
600
|
|
|
553
601
|
Example
|
|
554
602
|
|
|
555
603
|
```javascript
|
|
556
|
-
record
|
|
557
|
-
record.
|
|
558
|
-
record.name; // 'Doc 1'
|
|
559
|
-
record.rollbackAttributes();
|
|
560
|
-
record.name; // 'Untitled Document'
|
|
604
|
+
let record = store.createRecord('model');
|
|
605
|
+
record.dirtyType; // 'created'
|
|
561
606
|
```
|
|
562
607
|
|
|
563
|
-
@
|
|
564
|
-
@method rollbackAttributes
|
|
608
|
+
@property dirtyType
|
|
565
609
|
@public
|
|
610
|
+
@readonly
|
|
566
611
|
*/
|
|
612
|
+
get dirtyType(): 'created' | 'updated' | 'deleted' | '';
|
|
567
613
|
/**
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
Save the record and persist any changes to the record to an
|
|
573
|
-
external source via the adapter.
|
|
614
|
+
If `true` the adapter reported that it was unable to save local
|
|
615
|
+
changes to the backend for any reason other than a server-side
|
|
616
|
+
validation error.
|
|
574
617
|
|
|
575
618
|
Example
|
|
576
619
|
|
|
577
620
|
```javascript
|
|
578
|
-
record.
|
|
579
|
-
record.
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
// Error callback
|
|
621
|
+
record.isError; // false
|
|
622
|
+
record.set('foo', 'valid value');
|
|
623
|
+
record.save().then(null, function() {
|
|
624
|
+
record.isError; // true
|
|
583
625
|
});
|
|
584
626
|
```
|
|
585
627
|
|
|
586
|
-
|
|
587
|
-
argument it will be passed to your adapter via the snapshot.
|
|
588
|
-
|
|
589
|
-
```js
|
|
590
|
-
record.save({ adapterOptions: { subscribe: false } });
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
```app/adapters/post.js
|
|
594
|
-
import MyCustomAdapter from './custom-adapter';
|
|
595
|
-
|
|
596
|
-
export default class PostAdapter extends MyCustomAdapter {
|
|
597
|
-
updateRecord(store, type, snapshot) {
|
|
598
|
-
if (snapshot.adapterOptions.subscribe) {
|
|
599
|
-
// ...
|
|
600
|
-
}
|
|
601
|
-
// ...
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
@method save
|
|
628
|
+
@property isError
|
|
607
629
|
@public
|
|
608
|
-
@
|
|
609
|
-
@return {Promise} a promise that will be resolved when the adapter returns
|
|
610
|
-
successfully or rejected if the adapter returns with an error.
|
|
630
|
+
@readonly
|
|
611
631
|
*/
|
|
632
|
+
get isError(): boolean;
|
|
633
|
+
set isError(v: boolean);
|
|
612
634
|
/**
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
This will only work if the record has already finished loading.
|
|
635
|
+
If `true` the store is attempting to reload the record from the adapter.
|
|
616
636
|
|
|
617
637
|
Example
|
|
618
638
|
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
async reload = () => {
|
|
624
|
-
await this.args.model.reload();
|
|
625
|
-
// do something with the reloaded model
|
|
626
|
-
}
|
|
627
|
-
}
|
|
639
|
+
```javascript
|
|
640
|
+
record.isReloading; // false
|
|
641
|
+
record.reload();
|
|
642
|
+
record.isReloading; // true
|
|
628
643
|
```
|
|
629
644
|
|
|
630
|
-
@
|
|
645
|
+
@property isReloading
|
|
631
646
|
@public
|
|
632
|
-
@
|
|
633
|
-
|
|
634
|
-
@return {Promise} a promise that will be resolved with the record when the
|
|
635
|
-
adapter returns successfully or rejected if the adapter returns
|
|
636
|
-
with an error.
|
|
647
|
+
@readonly
|
|
637
648
|
*/
|
|
638
|
-
|
|
649
|
+
isReloading: boolean;
|
|
639
650
|
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
import Model, { belongsTo } from '@ember-data/model';
|
|
646
|
-
|
|
647
|
-
export default class BlogPost extends Model {
|
|
648
|
-
@belongsTo('user', { async: true, inverse: null }) author;
|
|
649
|
-
}
|
|
650
|
-
```
|
|
651
|
+
All ember models have an id property. This is an identifier
|
|
652
|
+
managed by an external source. These are always coerced to be
|
|
653
|
+
strings before being used internally. Note when declaring the
|
|
654
|
+
attributes for a model it is an error to an id
|
|
655
|
+
attribute.
|
|
651
656
|
|
|
652
|
-
|
|
653
|
-
|
|
657
|
+
```javascript
|
|
658
|
+
let record = store.createRecord('model');
|
|
659
|
+
record.id; // null
|
|
654
660
|
|
|
655
|
-
|
|
656
|
-
|
|
661
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
662
|
+
model.id; // '1'
|
|
657
663
|
```
|
|
658
664
|
|
|
659
|
-
|
|
660
|
-
and manipulation of a belongsTo relationship.
|
|
661
|
-
|
|
662
|
-
It is especially useful when you're dealing with `async` relationships
|
|
663
|
-
as it allows synchronous access to the relationship data if loaded, as
|
|
664
|
-
well as APIs for loading, reloading the data or accessing available
|
|
665
|
-
information without triggering a load.
|
|
666
|
-
|
|
667
|
-
It may also be useful when using `sync` relationships that need to be
|
|
668
|
-
loaded/reloaded with more precise timing than marking the
|
|
669
|
-
relationship as `async` and relying on autofetch would have allowed.
|
|
670
|
-
|
|
671
|
-
However,keep in mind that marking a relationship as `async: false` will introduce
|
|
672
|
-
bugs into your application if the data is not always guaranteed to be available
|
|
673
|
-
by the time the relationship is accessed. Ergo, it is recommended when using this
|
|
674
|
-
approach to utilize `links` for unloaded relationship state instead of identifiers.
|
|
675
|
-
|
|
676
|
-
Reference APIs are entangled with the relationship's underlying state,
|
|
677
|
-
thus any getters or cached properties that utilize these will properly
|
|
678
|
-
invalidate if the relationship state changes.
|
|
679
|
-
|
|
680
|
-
References are "stable", meaning that multiple calls to retrieve the reference
|
|
681
|
-
for a given relationship will always return the same HasManyReference.
|
|
682
|
-
|
|
683
|
-
@method belongsTo
|
|
665
|
+
@property id
|
|
684
666
|
@public
|
|
685
|
-
@param {String} name of the relationship
|
|
686
|
-
@since 2.5.0
|
|
687
|
-
@return {BelongsToReference} reference for this relationship
|
|
688
667
|
*/
|
|
668
|
+
get id(): string | null;
|
|
669
|
+
set id(id: string | null);
|
|
670
|
+
toString(): string;
|
|
689
671
|
/**
|
|
690
|
-
|
|
672
|
+
@property currentState
|
|
673
|
+
@private
|
|
674
|
+
*/
|
|
675
|
+
get currentState(): RecordState;
|
|
676
|
+
set currentState(_v: RecordState);
|
|
677
|
+
/**
|
|
678
|
+
The store service instance which created this record instance
|
|
691
679
|
|
|
692
|
-
|
|
680
|
+
@property store
|
|
681
|
+
@public
|
|
682
|
+
*/
|
|
683
|
+
/**
|
|
684
|
+
When the record is in the `invalid` state this object will contain
|
|
685
|
+
any errors returned by the adapter. When present the errors hash
|
|
686
|
+
contains keys corresponding to the invalid property names
|
|
687
|
+
and values which are arrays of Javascript objects with two keys:
|
|
693
688
|
|
|
694
|
-
|
|
695
|
-
|
|
689
|
+
- `message` A string containing the error message from the backend
|
|
690
|
+
- `attribute` The name of the property associated with this error message
|
|
696
691
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
692
|
+
```javascript
|
|
693
|
+
record.errors.length; // 0
|
|
694
|
+
record.set('foo', 'invalid value');
|
|
695
|
+
record.save().catch(function() {
|
|
696
|
+
record.errors.foo;
|
|
697
|
+
// [{message: 'foo should be a number.', attribute: 'foo'}]
|
|
698
|
+
});
|
|
700
699
|
```
|
|
701
700
|
|
|
702
|
-
|
|
703
|
-
|
|
701
|
+
The `errors` property is useful for displaying error messages to
|
|
702
|
+
the user.
|
|
704
703
|
|
|
705
|
-
```
|
|
706
|
-
|
|
704
|
+
```handlebars
|
|
705
|
+
<label>Username: <Input @value={{@model.username}} /> </label>
|
|
706
|
+
{{#each @model.errors.username as |error|}}
|
|
707
|
+
<div class="error">
|
|
708
|
+
{{error.message}}
|
|
709
|
+
</div>
|
|
710
|
+
{{/each}}
|
|
711
|
+
<label>Email: <Input @value={{@model.email}} /> </label>
|
|
712
|
+
{{#each @model.errors.email as |error|}}
|
|
713
|
+
<div class="error">
|
|
714
|
+
{{error.message}}
|
|
715
|
+
</div>
|
|
716
|
+
{{/each}}
|
|
707
717
|
```
|
|
708
718
|
|
|
709
|
-
A `HasManyReference` is a low-level API that allows access
|
|
710
|
-
and manipulation of a hasMany relationship.
|
|
711
|
-
|
|
712
|
-
It is especially useful when you are dealing with `async` relationships
|
|
713
|
-
as it allows synchronous access to the relationship data if loaded, as
|
|
714
|
-
well as APIs for loading, reloading the data or accessing available
|
|
715
|
-
information without triggering a load.
|
|
716
|
-
|
|
717
|
-
It may also be useful when using `sync` relationships with `@ember-data/model`
|
|
718
|
-
that need to be loaded/reloaded with more precise timing than marking the
|
|
719
|
-
relationship as `async` and relying on autofetch would have allowed.
|
|
720
719
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
by the time the relationship is accessed. Ergo, it is recommended when using this
|
|
724
|
-
approach to utilize `links` for unloaded relationship state instead of identifiers.
|
|
720
|
+
You can also access the special `messages` property on the error
|
|
721
|
+
object to get an array of all the error strings.
|
|
725
722
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
723
|
+
```handlebars
|
|
724
|
+
{{#each @model.errors.messages as |message|}}
|
|
725
|
+
<div class="error">
|
|
726
|
+
{{message}}
|
|
727
|
+
</div>
|
|
728
|
+
{{/each}}
|
|
729
|
+
```
|
|
729
730
|
|
|
730
|
-
|
|
731
|
-
|
|
731
|
+
@property errors
|
|
732
|
+
@public
|
|
733
|
+
*/
|
|
734
|
+
get errors(): Errors;
|
|
735
|
+
/**
|
|
736
|
+
This property holds the `AdapterError` object with which
|
|
737
|
+
last adapter operation was rejected.
|
|
732
738
|
|
|
733
|
-
@
|
|
739
|
+
@property adapterError
|
|
734
740
|
@public
|
|
735
|
-
@param {String} name of the relationship
|
|
736
|
-
@since 2.5.0
|
|
737
|
-
@return {HasManyReference} reference for this relationship
|
|
738
741
|
*/
|
|
742
|
+
get adapterError(): unknown;
|
|
743
|
+
set adapterError(v: unknown);
|
|
744
|
+
notifyPropertyChange(prop: string): this;
|
|
745
|
+
/** @internal */
|
|
746
|
+
attr(): void;
|
|
739
747
|
/**
|
|
740
748
|
Given a callback, iterates over each of the relationships in the model,
|
|
741
749
|
invoking the callback with the name of each relationship and its relationship
|
|
@@ -765,7 +773,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
765
773
|
|
|
766
774
|
Example
|
|
767
775
|
|
|
768
|
-
```app/serializers/application.js
|
|
776
|
+
```js [app/serializers/application.js]
|
|
769
777
|
import JSONSerializer from '@ember-data/serializer/json';
|
|
770
778
|
|
|
771
779
|
export default class ApplicationSerializer extends JSONSerializer {
|
|
@@ -784,7 +792,6 @@ declare module '@ember-data/model/-private/model' {
|
|
|
784
792
|
}
|
|
785
793
|
```
|
|
786
794
|
|
|
787
|
-
@method eachRelationship
|
|
788
795
|
@public
|
|
789
796
|
@param {Function} callback the callback to invoke
|
|
790
797
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
@@ -793,17 +800,10 @@ declare module '@ember-data/model/-private/model' {
|
|
|
793
800
|
relationshipFor(name: string): LegacyRelationshipField | undefined;
|
|
794
801
|
inverseFor(name: string): LegacyRelationshipField | null;
|
|
795
802
|
eachAttribute<T>(callback: (this: NoInfer<T> | undefined, key: isSubClass<this> extends true ? MaybeAttrFields<this> : string, meta: LegacyAttributeField) => void, binding?: T): void;
|
|
796
|
-
static isModel: boolean;
|
|
797
803
|
/**
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
To create instances of `Model` in a clean state, use `store.push`
|
|
802
|
-
|
|
803
|
-
@method create
|
|
804
|
-
@private
|
|
805
|
-
@static
|
|
806
|
-
*/
|
|
804
|
+
* @internal
|
|
805
|
+
*/
|
|
806
|
+
static isModel: boolean;
|
|
807
807
|
/**
|
|
808
808
|
Represents the model's class name as a string. This can be used to look up the model's class name through
|
|
809
809
|
`Store`'s modelFor method.
|
|
@@ -831,9 +831,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
831
831
|
```
|
|
832
832
|
@property modelName
|
|
833
833
|
@public
|
|
834
|
-
@type String
|
|
835
834
|
@readonly
|
|
836
|
-
@static
|
|
837
835
|
*/
|
|
838
836
|
static modelName: string;
|
|
839
837
|
/**
|
|
@@ -841,7 +839,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
841
839
|
|
|
842
840
|
For example, if you define a model like this:
|
|
843
841
|
|
|
844
|
-
```app/models/post.js
|
|
842
|
+
```js [app/models/post.js]
|
|
845
843
|
import Model, { hasMany } from '@ember-data/model';
|
|
846
844
|
|
|
847
845
|
export default class PostModel extends Model {
|
|
@@ -851,9 +849,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
851
849
|
|
|
852
850
|
Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`.
|
|
853
851
|
|
|
854
|
-
@method typeForRelationship
|
|
855
852
|
@public
|
|
856
|
-
@static
|
|
857
853
|
@param {String} name the name of the relationship
|
|
858
854
|
@param {store} store an instance of Store
|
|
859
855
|
@return {Model} the type of the relationship, or undefined
|
|
@@ -865,7 +861,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
865
861
|
|
|
866
862
|
For example, if you define models like this:
|
|
867
863
|
|
|
868
|
-
```app/models/post.js
|
|
864
|
+
```js [app/models/post.js]
|
|
869
865
|
import Model, { hasMany } from '@ember-data/model';
|
|
870
866
|
|
|
871
867
|
export default class PostModel extends Model {
|
|
@@ -873,7 +869,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
873
869
|
}
|
|
874
870
|
```
|
|
875
871
|
|
|
876
|
-
```app/models/message.js
|
|
872
|
+
```js [app/models/message.js]
|
|
877
873
|
import Model, { belongsTo } from '@ember-data/model';
|
|
878
874
|
|
|
879
875
|
export default class MessageModel extends Model {
|
|
@@ -886,9 +882,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
886
882
|
store.modelFor('message').inverseFor('owner', store) // { type: 'post', name: 'comments', kind: 'hasMany' }
|
|
887
883
|
```
|
|
888
884
|
|
|
889
|
-
@method inverseFor
|
|
890
885
|
@public
|
|
891
|
-
@static
|
|
892
886
|
@param {String} name the name of the relationship
|
|
893
887
|
@param {Store} store
|
|
894
888
|
@return {Object} the inverse relationship, or null
|
|
@@ -903,7 +897,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
903
897
|
|
|
904
898
|
For example, given the following model definition:
|
|
905
899
|
|
|
906
|
-
```app/models/blog.js
|
|
900
|
+
```js [app/models/blog.js]
|
|
907
901
|
import Model, { belongsTo, hasMany } from '@ember-data/model';
|
|
908
902
|
|
|
909
903
|
export default class BlogModel extends Model {
|
|
@@ -931,9 +925,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
931
925
|
|
|
932
926
|
@property relationships
|
|
933
927
|
@public
|
|
934
|
-
@
|
|
935
|
-
@type Map
|
|
936
|
-
@readOnly
|
|
928
|
+
@readonly
|
|
937
929
|
*/
|
|
938
930
|
static get relationships(): Map<string, LegacyRelationshipField[]>;
|
|
939
931
|
/**
|
|
@@ -941,7 +933,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
941
933
|
by the relationship kind. For example, given a model with this
|
|
942
934
|
definition:
|
|
943
935
|
|
|
944
|
-
```app/models/blog.js
|
|
936
|
+
```js [app/models/blog.js]
|
|
945
937
|
import Model, { belongsTo, hasMany } from '@ember-data/model';
|
|
946
938
|
|
|
947
939
|
export default class BlogModel extends Model {
|
|
@@ -966,9 +958,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
966
958
|
|
|
967
959
|
@property relationshipNames
|
|
968
960
|
@public
|
|
969
|
-
@
|
|
970
|
-
@type Object
|
|
971
|
-
@readOnly
|
|
961
|
+
@readonly
|
|
972
962
|
*/
|
|
973
963
|
static get relationshipNames(): {
|
|
974
964
|
hasMany: string[];
|
|
@@ -981,7 +971,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
981
971
|
|
|
982
972
|
For example, given a model with this definition:
|
|
983
973
|
|
|
984
|
-
```app/models/blog.js
|
|
974
|
+
```js [app/models/blog.js]
|
|
985
975
|
import Model, { belongsTo, hasMany } from '@ember-data/model';
|
|
986
976
|
|
|
987
977
|
export default class BlogModel extends Model {
|
|
@@ -1003,9 +993,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1003
993
|
|
|
1004
994
|
@property relatedTypes
|
|
1005
995
|
@public
|
|
1006
|
-
@
|
|
1007
|
-
@type Array
|
|
1008
|
-
@readOnly
|
|
996
|
+
@readonly
|
|
1009
997
|
*/
|
|
1010
998
|
static get relatedTypes(): string[];
|
|
1011
999
|
/**
|
|
@@ -1015,7 +1003,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1015
1003
|
For example, given a model with this
|
|
1016
1004
|
definition:
|
|
1017
1005
|
|
|
1018
|
-
```app/models/blog.js
|
|
1006
|
+
```js [app/models/blog.js]
|
|
1019
1007
|
import Model, { belongsTo, hasMany } from '@ember-data/model';
|
|
1020
1008
|
|
|
1021
1009
|
export default class BlogModel extends Model {
|
|
@@ -1040,9 +1028,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1040
1028
|
|
|
1041
1029
|
@property relationshipsByName
|
|
1042
1030
|
@public
|
|
1043
|
-
@
|
|
1044
|
-
@type Map
|
|
1045
|
-
@readOnly
|
|
1031
|
+
@readonly
|
|
1046
1032
|
*/
|
|
1047
1033
|
static get relationshipsByName(): Map<string, LegacyRelationshipField>;
|
|
1048
1034
|
static get relationshipsObject(): Record<string, LegacyRelationshipField>;
|
|
@@ -1053,7 +1039,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1053
1039
|
|
|
1054
1040
|
For example:
|
|
1055
1041
|
|
|
1056
|
-
```app/models/blog.js
|
|
1042
|
+
```js [app/models/blog.js]
|
|
1057
1043
|
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
|
|
1058
1044
|
|
|
1059
1045
|
export default class BlogModel extends Model {
|
|
@@ -1083,9 +1069,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1083
1069
|
|
|
1084
1070
|
@property fields
|
|
1085
1071
|
@public
|
|
1086
|
-
@
|
|
1087
|
-
@type Map
|
|
1088
|
-
@readOnly
|
|
1072
|
+
@readonly
|
|
1089
1073
|
*/
|
|
1090
1074
|
static get fields(): Map<string, 'attribute' | 'belongsTo' | 'hasMany'>;
|
|
1091
1075
|
/**
|
|
@@ -1093,9 +1077,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1093
1077
|
invoking the callback with the name of each relationship and its relationship
|
|
1094
1078
|
descriptor.
|
|
1095
1079
|
|
|
1096
|
-
@method eachRelationship
|
|
1097
1080
|
@public
|
|
1098
|
-
@static
|
|
1099
1081
|
@param {Function} callback the callback to invoke
|
|
1100
1082
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
1101
1083
|
*/
|
|
@@ -1106,16 +1088,13 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1106
1088
|
returned just once, regardless of how many different relationships it has
|
|
1107
1089
|
with a model.
|
|
1108
1090
|
|
|
1109
|
-
@method eachRelatedType
|
|
1110
1091
|
@public
|
|
1111
|
-
@static
|
|
1112
1092
|
@param {Function} callback the callback to invoke
|
|
1113
1093
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
1114
1094
|
*/
|
|
1115
1095
|
static eachRelatedType<T>(callback: (this: T | undefined, type: string) => void, binding?: T): void;
|
|
1116
1096
|
/**
|
|
1117
1097
|
*
|
|
1118
|
-
* @method determineRelationshipType
|
|
1119
1098
|
* @private
|
|
1120
1099
|
* @deprecated
|
|
1121
1100
|
*/
|
|
@@ -1127,7 +1106,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1127
1106
|
|
|
1128
1107
|
Example
|
|
1129
1108
|
|
|
1130
|
-
```app/models/person.js
|
|
1109
|
+
```js [app/models/person.js]
|
|
1131
1110
|
import Model, { attr } from '@ember-data/model';
|
|
1132
1111
|
|
|
1133
1112
|
export default class PersonModel extends Model {
|
|
@@ -1154,9 +1133,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1154
1133
|
|
|
1155
1134
|
@property attributes
|
|
1156
1135
|
@public
|
|
1157
|
-
@
|
|
1158
|
-
@type {Map}
|
|
1159
|
-
@readOnly
|
|
1136
|
+
@readonly
|
|
1160
1137
|
*/
|
|
1161
1138
|
static get attributes(): Map<string, LegacyAttributeField>;
|
|
1162
1139
|
/**
|
|
@@ -1167,7 +1144,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1167
1144
|
|
|
1168
1145
|
Example
|
|
1169
1146
|
|
|
1170
|
-
```app/models/person.js
|
|
1147
|
+
```js [app/models/person.js]
|
|
1171
1148
|
import Model, { attr } from '@ember-data/model';
|
|
1172
1149
|
|
|
1173
1150
|
export default class PersonModel extends Model {
|
|
@@ -1193,9 +1170,7 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1193
1170
|
|
|
1194
1171
|
@property transformedAttributes
|
|
1195
1172
|
@public
|
|
1196
|
-
@
|
|
1197
|
-
@type {Map}
|
|
1198
|
-
@readOnly
|
|
1173
|
+
@readonly
|
|
1199
1174
|
*/
|
|
1200
1175
|
static get transformedAttributes(): Map<string, string>;
|
|
1201
1176
|
/**
|
|
@@ -1236,11 +1211,9 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1236
1211
|
// birthday {type: "date", kind: 'attribute', options: Object, parentType: function, name: "birthday"}
|
|
1237
1212
|
```
|
|
1238
1213
|
|
|
1239
|
-
@method eachAttribute
|
|
1240
1214
|
@public
|
|
1241
1215
|
@param {Function} callback The callback to execute
|
|
1242
1216
|
@param {Object} [binding] the value to which the callback's `this` should be bound
|
|
1243
|
-
@static
|
|
1244
1217
|
*/
|
|
1245
1218
|
static eachAttribute<T, Schema extends Model>(callback: (this: T | undefined, key: MaybeAttrFields<Schema>, attribute: LegacyAttributeField) => void, binding?: T): void;
|
|
1246
1219
|
/**
|
|
@@ -1282,19 +1255,15 @@ declare module '@ember-data/model/-private/model' {
|
|
|
1282
1255
|
// birthday date
|
|
1283
1256
|
```
|
|
1284
1257
|
|
|
1285
|
-
@method eachTransformedAttribute
|
|
1286
1258
|
@public
|
|
1287
1259
|
@param {Function} callback The callback to execute
|
|
1288
1260
|
@param {Object} [binding] the value to which the callback's `this` should be bound
|
|
1289
|
-
@static
|
|
1290
1261
|
*/
|
|
1291
1262
|
static eachTransformedAttribute<T, Schema extends Model>(callback: (this: T | undefined, key: Exclude<keyof Schema & string, keyof Model & string>, type: string) => void, binding?: T): void;
|
|
1292
1263
|
/**
|
|
1293
1264
|
Returns the name of the model class.
|
|
1294
1265
|
|
|
1295
|
-
@method toString
|
|
1296
1266
|
@public
|
|
1297
|
-
@static
|
|
1298
1267
|
*/
|
|
1299
1268
|
static toString(): string;
|
|
1300
1269
|
}
|