Skip to content

Commit 1639f70

Browse files
authored
Ensure changing arrays are notified. (#472)
1 parent 3b0eaed commit 1639f70

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

addon/record-data.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// eslint-disable-next-line ember/use-ember-data-rfc-395-imports
22
import { RecordData } from 'ember-data/-private';
3+
import { diffArray } from '@ember-data/model/-private';
34
import { recordDataFor } from '@ember-data/store/-private';
45
import { assert } from '@ember/debug';
56
import { typeOf } from '@ember/utils';
@@ -692,7 +693,11 @@ export default class FragmentRecordData extends RecordData {
692693
if (this._fragments[key]) {
693694
continue;
694695
}
695-
if ((updates[key] === null) !== (original[key] === null)) {
696+
const eitherIsNull = original[key] === null || updates[key] === null;
697+
if (
698+
eitherIsNull ||
699+
diffArray(original[key], updates[key]).firstChangeIndex !== null
700+
) {
696701
changedKeys.push(key);
697702
}
698703
}
@@ -727,7 +732,7 @@ export default class FragmentRecordData extends RecordData {
727732

728733
Object.assign(this._fragmentData, newCanonicalFragments);
729734
// update fragment arrays
730-
Object.keys(newCanonicalFragments).forEach((key) =>
735+
changedFragmentKeys?.forEach((key) =>
731736
this._fragmentArrayCache[key]?.notify()
732737
);
733738
}

tests/integration/render_test.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,95 @@ module('Integration | Rendering', function (hooks) {
103103
assert.dom('[data-product="0"]').hasText('The Strangler: 299.99');
104104
assert.dom('[data-product="1"]').hasText('Tears of Lys: 499.99');
105105
});
106+
107+
test('fragment array data pushed', async function (assert) {
108+
this.order = store.createRecord('order', { id: 'an-id' });
109+
110+
await render(
111+
hbs`
112+
Orders
113+
<ul>
114+
{{#each this.order.products as |product idx|}}
115+
<li data-product="{{idx}}">{{product.name}}: {{product.price}}</li>
116+
{{/each}}
117+
</ul>
118+
`
119+
);
120+
121+
assert.dom('[data-product]').doesNotExist();
122+
123+
store.push({
124+
data: [
125+
{
126+
id: this.order.id,
127+
type: 'order',
128+
attributes: {
129+
products: [
130+
{
131+
name: 'Tears of Lys',
132+
price: '499.99',
133+
},
134+
],
135+
},
136+
relationships: {},
137+
},
138+
],
139+
});
140+
141+
await settled();
142+
143+
assert.dom('[data-product]').exists({ count: 1 });
144+
assert.dom('[data-product="0"]').hasText('Tears of Lys: 499.99');
145+
146+
store.push({
147+
data: [
148+
{
149+
id: this.order.id,
150+
type: 'order',
151+
attributes: {
152+
products: [
153+
{
154+
name: 'The Strangler',
155+
price: '299.99',
156+
},
157+
{
158+
name: 'Tears of Lys',
159+
price: '499.99',
160+
},
161+
],
162+
},
163+
relationships: {},
164+
},
165+
],
166+
});
167+
168+
await settled();
169+
170+
assert.dom('[data-product]').exists({ count: 2 });
171+
assert.dom('[data-product="0"]').hasText('The Strangler: 299.99');
172+
assert.dom('[data-product="1"]').hasText('Tears of Lys: 499.99');
173+
174+
store.push({
175+
data: [
176+
{
177+
id: this.order.id,
178+
type: 'order',
179+
attributes: {
180+
products: [
181+
{
182+
name: 'The Strangler',
183+
price: '299.99',
184+
},
185+
],
186+
},
187+
relationships: {},
188+
},
189+
],
190+
});
191+
192+
await settled();
193+
194+
assert.dom('[data-product]').exists({ count: 1 });
195+
assert.dom('[data-product="0"]').hasText('The Strangler: 299.99');
196+
});
106197
});

0 commit comments

Comments
 (0)