@ember-data/model 4.8.0-alpha.0 → 4.8.0-alpha.3
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/addon/-private/attr.js +13 -2
- package/addon/-private/belongs-to.js +9 -3
- package/addon/-private/errors.ts +6 -6
- package/addon/-private/has-many.js +7 -3
- package/addon/-private/legacy-data-fetch.js +9 -7
- package/addon/-private/legacy-data-utils.ts +1 -1
- package/addon/-private/legacy-relationships-support.ts +33 -42
- package/addon/-private/many-array.ts +13 -7
- package/addon/-private/model-for-mixin.ts +2 -4
- package/addon/-private/model.js +425 -108
- package/addon/-private/notify-changes.ts +1 -1
- package/addon/-private/promise-many-array.ts +170 -112
- package/addon/-private/record-state.ts +61 -38
- package/addon/-private/references/belongs-to.ts +5 -5
- package/addon/-private/references/has-many.ts +6 -8
- package/addon/-private/relationship-meta.ts +2 -2
- package/index.js +1 -0
- package/package.json +6 -7
package/addon/-private/attr.js
CHANGED
|
@@ -130,13 +130,24 @@ function attr(type, options) {
|
|
|
130
130
|
return computed({
|
|
131
131
|
get(key) {
|
|
132
132
|
if (DEBUG) {
|
|
133
|
-
if (['
|
|
133
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
134
134
|
throw new Error(
|
|
135
135
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your attr on ${this.constructor.toString()}`
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
+
if (this.isDestroyed || this.isDestroying) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
139
142
|
let recordData = recordDataFor(this);
|
|
143
|
+
// TODO hasAttr is not spec'd
|
|
144
|
+
// essentially this is needed because
|
|
145
|
+
// there is a difference between "undefined" meaning never set
|
|
146
|
+
// and "undefined" meaning set to "undefined". In the "key present"
|
|
147
|
+
// case we want to return undefined. In the "key absent" case
|
|
148
|
+
// we want to return getDefaultValue. RecordDataV2 can fix this
|
|
149
|
+
// by providing the attributes blob such that we can make our
|
|
150
|
+
// own determination.
|
|
140
151
|
if (recordData.hasAttr(key)) {
|
|
141
152
|
return recordData.getAttr(key);
|
|
142
153
|
} else {
|
|
@@ -145,7 +156,7 @@ function attr(type, options) {
|
|
|
145
156
|
},
|
|
146
157
|
set(key, value) {
|
|
147
158
|
if (DEBUG) {
|
|
148
|
-
if (['
|
|
159
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
149
160
|
throw new Error(
|
|
150
161
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your attr on ${this.constructor.toString()}`
|
|
151
162
|
);
|
|
@@ -98,7 +98,7 @@ import { computedMacroWithOptionalParams } from './util';
|
|
|
98
98
|
a related resource is known to exist and it has not been loaded.
|
|
99
99
|
|
|
100
100
|
```
|
|
101
|
-
let post = comment.
|
|
101
|
+
let post = comment.post;
|
|
102
102
|
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -143,10 +143,16 @@ function belongsTo(modelName, options) {
|
|
|
143
143
|
|
|
144
144
|
return computed({
|
|
145
145
|
get(key) {
|
|
146
|
+
// this is a legacy behavior we may not carry into a new model setup
|
|
147
|
+
// it's better to error on disconnected records so users find errors
|
|
148
|
+
// in their logic.
|
|
149
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
146
152
|
const support = LEGACY_SUPPORT.lookup(this);
|
|
147
153
|
|
|
148
154
|
if (DEBUG) {
|
|
149
|
-
if (['
|
|
155
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
150
156
|
throw new Error(
|
|
151
157
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your belongsTo on ${this.constructor.toString()}`
|
|
152
158
|
);
|
|
@@ -177,7 +183,7 @@ function belongsTo(modelName, options) {
|
|
|
177
183
|
set(key, value) {
|
|
178
184
|
const support = LEGACY_SUPPORT.lookup(this);
|
|
179
185
|
if (DEBUG) {
|
|
180
|
-
if (['
|
|
186
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
181
187
|
throw new Error(
|
|
182
188
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your belongsTo on ${this.constructor.toString()}`
|
|
183
189
|
);
|
package/addon/-private/errors.ts
CHANGED
|
@@ -123,7 +123,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
123
123
|
email: 'invalidEmail'
|
|
124
124
|
});
|
|
125
125
|
user.save().catch(function(){
|
|
126
|
-
user.
|
|
126
|
+
user.errors.errorsFor('email'); // returns:
|
|
127
127
|
// [{attribute: "email", message: "Doesn't look like a valid email."}]
|
|
128
128
|
});
|
|
129
129
|
```
|
|
@@ -219,7 +219,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
219
219
|
|
|
220
220
|
Example
|
|
221
221
|
```javascript
|
|
222
|
-
let errors =
|
|
222
|
+
let errors = user.errors;
|
|
223
223
|
|
|
224
224
|
// add multiple errors
|
|
225
225
|
errors.add('password', [
|
|
@@ -293,7 +293,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
293
293
|
Example:
|
|
294
294
|
|
|
295
295
|
```javascript
|
|
296
|
-
let errors =
|
|
296
|
+
let errors = user.errors;
|
|
297
297
|
errors.add('phone', ['error-1', 'error-2']);
|
|
298
298
|
|
|
299
299
|
errors.errorsFor('phone');
|
|
@@ -344,7 +344,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
344
344
|
Example:
|
|
345
345
|
|
|
346
346
|
```javascript
|
|
347
|
-
let errors =
|
|
347
|
+
let errors = user.errors;
|
|
348
348
|
errors.add('username', ['error-a']);
|
|
349
349
|
errors.add('phone', ['error-1', 'error-2']);
|
|
350
350
|
|
|
@@ -369,7 +369,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
369
369
|
errors.errorsFor('phone');
|
|
370
370
|
// => undefined
|
|
371
371
|
|
|
372
|
-
errors.
|
|
372
|
+
errors.messages
|
|
373
373
|
// => []
|
|
374
374
|
```
|
|
375
375
|
@method clear
|
|
@@ -406,7 +406,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
406
406
|
export default class UserEditController extends Controller {
|
|
407
407
|
@action
|
|
408
408
|
save(user) {
|
|
409
|
-
if (user.
|
|
409
|
+
if (user.errors.has('email')) {
|
|
410
410
|
return alert('Please update your email before attempting to save.');
|
|
411
411
|
}
|
|
412
412
|
user.save();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@module @ember-data/model
|
|
3
3
|
*/
|
|
4
|
+
import { A } from '@ember/array';
|
|
4
5
|
import { assert, inspect } from '@ember/debug';
|
|
5
6
|
import { computed } from '@ember/object';
|
|
6
7
|
import { DEBUG } from '@glimmer/env';
|
|
@@ -132,7 +133,7 @@ import { computedMacroWithOptionalParams } from './util';
|
|
|
132
133
|
when any of the known related resources have not been loaded.
|
|
133
134
|
|
|
134
135
|
```
|
|
135
|
-
post.
|
|
136
|
+
post.comments.forEach((comment) => {
|
|
136
137
|
|
|
137
138
|
});
|
|
138
139
|
|
|
@@ -183,17 +184,20 @@ function hasMany(type, options) {
|
|
|
183
184
|
return computed({
|
|
184
185
|
get(key) {
|
|
185
186
|
if (DEBUG) {
|
|
186
|
-
if (['
|
|
187
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
187
188
|
throw new Error(
|
|
188
189
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your hasMany on ${this.constructor.toString()}`
|
|
189
190
|
);
|
|
190
191
|
}
|
|
191
192
|
}
|
|
193
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
194
|
+
return A();
|
|
195
|
+
}
|
|
192
196
|
return LEGACY_SUPPORT.lookup(this).getHasMany(key);
|
|
193
197
|
},
|
|
194
198
|
set(key, records) {
|
|
195
199
|
if (DEBUG) {
|
|
196
|
-
if (['
|
|
200
|
+
if (['currentState'].indexOf(key) !== -1) {
|
|
197
201
|
throw new Error(
|
|
198
202
|
`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your hasMany on ${this.constructor.toString()}`
|
|
199
203
|
);
|
|
@@ -8,6 +8,7 @@ import { DEPRECATE_RSVP_PROMISE } from '@ember-data/private-build-infra/deprecat
|
|
|
8
8
|
import { iterateData, normalizeResponseHelper } from './legacy-data-utils';
|
|
9
9
|
|
|
10
10
|
export function _findHasMany(adapter, store, identifier, link, relationship, options) {
|
|
11
|
+
const record = store._instanceCache.getRecord(identifier);
|
|
11
12
|
const snapshot = store._instanceCache.createSnapshot(identifier, options);
|
|
12
13
|
let modelClass = store.modelFor(relationship.type);
|
|
13
14
|
let useLink = !link || typeof link === 'string';
|
|
@@ -18,7 +19,7 @@ export function _findHasMany(adapter, store, identifier, link, relationship, opt
|
|
|
18
19
|
promise = guardDestroyedStore(promise, store, label);
|
|
19
20
|
promise = promise.then(
|
|
20
21
|
(adapterPayload) => {
|
|
21
|
-
if (!_objectIsAlive(
|
|
22
|
+
if (!_objectIsAlive(record)) {
|
|
22
23
|
if (DEPRECATE_RSVP_PROMISE) {
|
|
23
24
|
deprecate(
|
|
24
25
|
`A Promise for fetching ${relationship.type} did not resolve by the time your model was destroyed. This will error in a future release.`,
|
|
@@ -57,13 +58,14 @@ export function _findHasMany(adapter, store, identifier, link, relationship, opt
|
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
if (DEPRECATE_RSVP_PROMISE) {
|
|
60
|
-
promise = _guard(promise, _bind(_objectIsAlive,
|
|
61
|
+
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
return promise;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
export function _findBelongsTo(store, identifier, link, relationship, options) {
|
|
68
|
+
const record = store._instanceCache.getRecord(identifier);
|
|
67
69
|
let adapter = store.adapterFor(identifier.type);
|
|
68
70
|
|
|
69
71
|
assert(`You tried to load a belongsTo relationship but you have no adapter (for ${identifier.type})`, adapter);
|
|
@@ -79,11 +81,11 @@ export function _findBelongsTo(store, identifier, link, relationship, options) {
|
|
|
79
81
|
let label = `DS: Handle Adapter#findBelongsTo of ${identifier.type} : ${relationship.type}`;
|
|
80
82
|
|
|
81
83
|
promise = guardDestroyedStore(promise, store, label);
|
|
82
|
-
promise = _guard(promise, _bind(_objectIsAlive,
|
|
84
|
+
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
83
85
|
|
|
84
86
|
promise = promise.then(
|
|
85
87
|
(adapterPayload) => {
|
|
86
|
-
if (!_objectIsAlive(
|
|
88
|
+
if (!_objectIsAlive(record)) {
|
|
87
89
|
if (DEPRECATE_RSVP_PROMISE) {
|
|
88
90
|
deprecate(
|
|
89
91
|
`A Promise for fetching ${relationship.type} did not resolve by the time your model was destroyed. This will error in a future release.`,
|
|
@@ -123,7 +125,7 @@ export function _findBelongsTo(store, identifier, link, relationship, options) {
|
|
|
123
125
|
);
|
|
124
126
|
|
|
125
127
|
if (DEPRECATE_RSVP_PROMISE) {
|
|
126
|
-
promise = _guard(promise, _bind(_objectIsAlive,
|
|
128
|
+
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
return promise;
|
|
@@ -229,8 +231,8 @@ function ensureRelationshipIsSetToParent(payload, parentIdentifier, store, paren
|
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
|
|
232
|
-
function getInverse(store,
|
|
233
|
-
return recordDataFindInverseRelationshipInfo(store,
|
|
234
|
+
function getInverse(store, parentIdentifier, parentRelationship, type) {
|
|
235
|
+
return recordDataFindInverseRelationshipInfo(store, parentIdentifier, parentRelationship, type);
|
|
234
236
|
}
|
|
235
237
|
|
|
236
238
|
function recordDataFindInverseRelationshipInfo(store, parentIdentifier, parentRelationship, type) {
|
|
@@ -2,7 +2,7 @@ import { assert } from '@ember/debug';
|
|
|
2
2
|
import { DEBUG } from '@glimmer/env';
|
|
3
3
|
|
|
4
4
|
import type Store from '@ember-data/store';
|
|
5
|
-
import type ShimModelClass from '@ember-data/store/-private/model/shim-model-class';
|
|
5
|
+
import type ShimModelClass from '@ember-data/store/-private/legacy-model-support/shim-model-class';
|
|
6
6
|
import type { JsonApiDocument } from '@ember-data/types/q/ember-data-json-api';
|
|
7
7
|
import type { StableExistingRecordIdentifier, StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
8
8
|
import type { AdapterPayload } from '@ember-data/types/q/minimum-adapter-interface';
|
|
@@ -13,11 +13,10 @@ import type {
|
|
|
13
13
|
import type { UpgradedMeta } from '@ember-data/record-data/-private/graph/-edge-definition';
|
|
14
14
|
import type { RelationshipState } from '@ember-data/record-data/-private/graph/-state';
|
|
15
15
|
import type Store from '@ember-data/store';
|
|
16
|
-
import type { InternalModel } from '@ember-data/store/-private';
|
|
17
16
|
import { recordDataFor, recordIdentifierFor, storeFor } from '@ember-data/store/-private';
|
|
18
|
-
import
|
|
17
|
+
import { IdentifierCache } from '@ember-data/store/-private/caches/identifier-cache';
|
|
19
18
|
import type { DSModel } from '@ember-data/types/q/ds-model';
|
|
20
|
-
import
|
|
19
|
+
import { ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';
|
|
21
20
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
22
21
|
import type { RecordData } from '@ember-data/types/q/record-data';
|
|
23
22
|
import type { JsonApiRelationship } from '@ember-data/types/q/record-data-json-api';
|
|
@@ -141,7 +140,7 @@ export class LegacySupport {
|
|
|
141
140
|
`You looked up the '${key}' relationship on a '${identifier.type}' with id ${
|
|
142
141
|
identifier.id || 'null'
|
|
143
142
|
} but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (\`belongsTo({ async: true })\`)`,
|
|
144
|
-
toReturn === null ||
|
|
143
|
+
toReturn === null || store._instanceCache.recordIsLoaded(relatedIdentifier, true)
|
|
145
144
|
);
|
|
146
145
|
return toReturn;
|
|
147
146
|
}
|
|
@@ -447,7 +446,7 @@ export class LegacySupport {
|
|
|
447
446
|
return resolve(null);
|
|
448
447
|
}
|
|
449
448
|
|
|
450
|
-
const
|
|
449
|
+
const identifier = resource.data ? this.store.identifierCache.getOrCreateRecordIdentifier(resource.data) : null;
|
|
451
450
|
|
|
452
451
|
let { isStale, hasDematerializedInverse, hasReceivedData, isEmpty, shouldForceReload } = resource._relationship
|
|
453
452
|
.state as RelationshipState;
|
|
@@ -458,9 +457,9 @@ export class LegacySupport {
|
|
|
458
457
|
resource.links.related &&
|
|
459
458
|
(shouldForceReload || hasDematerializedInverse || isStale || (!allInverseRecordsAreLoaded && !isEmpty));
|
|
460
459
|
|
|
461
|
-
if (
|
|
460
|
+
if (identifier) {
|
|
462
461
|
// short circuit if we are already loading
|
|
463
|
-
let pendingRequest = this.store._fetchManager.getPendingFetch(
|
|
462
|
+
let pendingRequest = this.store._fetchManager.getPendingFetch(identifier, options);
|
|
464
463
|
if (pendingRequest) {
|
|
465
464
|
return pendingRequest;
|
|
466
465
|
}
|
|
@@ -485,22 +484,21 @@ export class LegacySupport {
|
|
|
485
484
|
return resolve(null);
|
|
486
485
|
}
|
|
487
486
|
|
|
488
|
-
if (!
|
|
489
|
-
assert(`No
|
|
487
|
+
if (!identifier) {
|
|
488
|
+
assert(`No Information found for ${resource.lid}`, identifier);
|
|
490
489
|
}
|
|
491
490
|
|
|
492
|
-
return this.store._instanceCache._fetchDataIfNeededForIdentifier(
|
|
491
|
+
return this.store._instanceCache._fetchDataIfNeededForIdentifier(identifier, options);
|
|
493
492
|
}
|
|
494
493
|
|
|
495
494
|
let resourceIsLocal = !localDataIsEmpty && resource.data.id === null;
|
|
496
495
|
|
|
497
|
-
if (
|
|
498
|
-
return resolve(
|
|
496
|
+
if (identifier && resourceIsLocal) {
|
|
497
|
+
return resolve(identifier);
|
|
499
498
|
}
|
|
500
499
|
|
|
501
500
|
// fetch by data
|
|
502
|
-
if (
|
|
503
|
-
let identifier = internalModel.identifier;
|
|
501
|
+
if (identifier && !localDataIsEmpty) {
|
|
504
502
|
assertIdentifierHasId(identifier);
|
|
505
503
|
|
|
506
504
|
return this.store._fetchManager.scheduleFetch(identifier, options);
|
|
@@ -512,10 +510,6 @@ export class LegacySupport {
|
|
|
512
510
|
}
|
|
513
511
|
|
|
514
512
|
destroy() {
|
|
515
|
-
assert(
|
|
516
|
-
'Cannot destroy an internalModel while its record is materialized',
|
|
517
|
-
!this.record || this.record.isDestroyed || this.record.isDestroying
|
|
518
|
-
);
|
|
519
513
|
this.isDestroying = true;
|
|
520
514
|
|
|
521
515
|
const cache = this._manyArrayCache;
|
|
@@ -625,7 +619,14 @@ function assertRecordsPassedToHasMany(records: RecordInstance[]) {
|
|
|
625
619
|
.map((r) => `${typeof r}`)
|
|
626
620
|
.join(', ')}`,
|
|
627
621
|
(function () {
|
|
628
|
-
return records.every((record) =>
|
|
622
|
+
return records.every((record) => {
|
|
623
|
+
try {
|
|
624
|
+
recordIdentifierFor(record);
|
|
625
|
+
return true;
|
|
626
|
+
} catch {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
});
|
|
629
630
|
})()
|
|
630
631
|
);
|
|
631
632
|
}
|
|
@@ -634,7 +635,10 @@ function extractRecordDatasFromRecords(records: RecordInstance[]): RecordData[]
|
|
|
634
635
|
return records.map(extractRecordDataFromRecord) as RecordData[];
|
|
635
636
|
}
|
|
636
637
|
|
|
637
|
-
type PromiseProxyRecord = {
|
|
638
|
+
type PromiseProxyRecord = {
|
|
639
|
+
then(): void;
|
|
640
|
+
content: RecordInstance | null | undefined;
|
|
641
|
+
};
|
|
638
642
|
|
|
639
643
|
function extractRecordDataFromRecord(recordOrPromiseRecord: PromiseProxyRecord | RecordInstance | null) {
|
|
640
644
|
if (!recordOrPromiseRecord) {
|
|
@@ -642,7 +646,7 @@ function extractRecordDataFromRecord(recordOrPromiseRecord: PromiseProxyRecord |
|
|
|
642
646
|
}
|
|
643
647
|
|
|
644
648
|
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
645
|
-
let content = recordOrPromiseRecord.
|
|
649
|
+
let content = recordOrPromiseRecord.content;
|
|
646
650
|
assert(
|
|
647
651
|
'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.',
|
|
648
652
|
content !== undefined
|
|
@@ -659,24 +663,15 @@ function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is
|
|
|
659
663
|
|
|
660
664
|
function anyUnloaded(store: Store, relationship: ManyRelationship) {
|
|
661
665
|
let state = relationship.currentState;
|
|
666
|
+
const cache = store._instanceCache;
|
|
662
667
|
const unloaded = state.find((s) => {
|
|
663
|
-
let
|
|
664
|
-
return
|
|
668
|
+
let isLoaded = cache.recordIsLoaded(s, true);
|
|
669
|
+
return !isLoaded;
|
|
665
670
|
});
|
|
666
671
|
|
|
667
672
|
return unloaded || false;
|
|
668
673
|
}
|
|
669
674
|
|
|
670
|
-
/**
|
|
671
|
-
* Flag indicating whether all inverse records are available
|
|
672
|
-
*
|
|
673
|
-
* true if the inverse exists and is loaded (not empty)
|
|
674
|
-
* true if there is no inverse
|
|
675
|
-
* false if the inverse exists and is not loaded (empty)
|
|
676
|
-
*
|
|
677
|
-
* @internal
|
|
678
|
-
* @return {boolean}
|
|
679
|
-
*/
|
|
680
675
|
function areAllInverseRecordsLoaded(store: Store, resource: JsonApiRelationship): boolean {
|
|
681
676
|
const cache = store.identifierCache;
|
|
682
677
|
|
|
@@ -684,7 +679,7 @@ function areAllInverseRecordsLoaded(store: Store, resource: JsonApiRelationship)
|
|
|
684
679
|
// treat as collection
|
|
685
680
|
// check for unloaded records
|
|
686
681
|
let hasEmptyRecords = resource.data.reduce((hasEmptyModel, resourceIdentifier) => {
|
|
687
|
-
return hasEmptyModel ||
|
|
682
|
+
return hasEmptyModel || isEmpty(store, cache, resourceIdentifier);
|
|
688
683
|
}, false);
|
|
689
684
|
|
|
690
685
|
return !hasEmptyRecords;
|
|
@@ -693,17 +688,13 @@ function areAllInverseRecordsLoaded(store: Store, resource: JsonApiRelationship)
|
|
|
693
688
|
if (!resource.data) {
|
|
694
689
|
return true;
|
|
695
690
|
} else {
|
|
696
|
-
|
|
697
|
-
return !internalModel.isEmpty;
|
|
691
|
+
return !isEmpty(store, cache, resource.data);
|
|
698
692
|
}
|
|
699
693
|
}
|
|
700
694
|
}
|
|
701
695
|
|
|
702
|
-
function
|
|
703
|
-
store: Store,
|
|
704
|
-
cache: IdentifierCache,
|
|
705
|
-
resource: ResourceIdentifierObject
|
|
706
|
-
): InternalModel {
|
|
696
|
+
function isEmpty(store: Store, cache: IdentifierCache, resource: ResourceIdentifierObject): boolean {
|
|
707
697
|
const identifier = cache.getOrCreateRecordIdentifier(resource);
|
|
708
|
-
|
|
698
|
+
const recordData = store._instanceCache.peek({ identifier, bucket: 'recordData' });
|
|
699
|
+
return !recordData || !!recordData.isEmpty?.();
|
|
709
700
|
}
|
|
@@ -10,8 +10,8 @@ import { all } from 'rsvp';
|
|
|
10
10
|
|
|
11
11
|
import type Store from '@ember-data/store';
|
|
12
12
|
import { PromiseArray, recordDataFor } from '@ember-data/store/-private';
|
|
13
|
-
import type
|
|
14
|
-
import type
|
|
13
|
+
import type ShimModelClass from '@ember-data/store/-private/legacy-model-support/shim-model-class';
|
|
14
|
+
import type { CreateRecordProperties } from '@ember-data/store/-private/store-service';
|
|
15
15
|
import type { DSModelSchema } from '@ember-data/types/q/ds-model';
|
|
16
16
|
import type { Links, PaginationLinks } from '@ember-data/types/q/ember-data-json-api';
|
|
17
17
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
@@ -306,16 +306,16 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
306
306
|
this._isDirty = false;
|
|
307
307
|
this._isUpdating = true;
|
|
308
308
|
let jsonApi = this.recordData.getHasMany(this.key);
|
|
309
|
+
const cache = this.store._instanceCache;
|
|
310
|
+
const idCache = this.store.identifierCache;
|
|
309
311
|
|
|
310
312
|
let identifiers: StableRecordIdentifier[] = [];
|
|
311
313
|
if (jsonApi.data) {
|
|
312
314
|
for (let i = 0; i < jsonApi.data.length; i++) {
|
|
313
|
-
|
|
314
|
-
let im = this.store._instanceCache._internalModelForResource(jsonApi.data[i]);
|
|
315
|
-
let shouldRemove = im._isDematerializing || im.isEmpty || !im.isLoaded;
|
|
315
|
+
const identifier = idCache.getOrCreateRecordIdentifier(jsonApi.data[i]);
|
|
316
316
|
|
|
317
|
-
if (
|
|
318
|
-
identifiers.push(
|
|
317
|
+
if (cache.recordIsLoaded(identifier, true)) {
|
|
318
|
+
identifiers.push(identifier);
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
}
|
|
@@ -348,6 +348,12 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
348
348
|
this._isUpdating = false;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
+
destroy() {
|
|
352
|
+
this._length = 0;
|
|
353
|
+
this.currentState = [];
|
|
354
|
+
return super.destroy();
|
|
355
|
+
}
|
|
356
|
+
|
|
351
357
|
/**
|
|
352
358
|
Reloads all of the records in the manyArray. If the manyArray
|
|
353
359
|
holds a relationship that was originally fetched using a links url
|
|
@@ -29,10 +29,8 @@ export default function modelForMixin(store: Store, normalizedModelName: string)
|
|
|
29
29
|
let mixin = MaybeMixin && MaybeMixin.class;
|
|
30
30
|
if (mixin) {
|
|
31
31
|
let ModelForMixin = Model.extend(mixin);
|
|
32
|
-
ModelForMixin.
|
|
33
|
-
|
|
34
|
-
__mixin: mixin,
|
|
35
|
-
});
|
|
32
|
+
ModelForMixin.__isMixin = true;
|
|
33
|
+
ModelForMixin.__mixin = mixin;
|
|
36
34
|
//Cache the class as a model
|
|
37
35
|
owner.register('model:' + normalizedModelName, ModelForMixin);
|
|
38
36
|
}
|