Skip to content

Commit 60f7487

Browse files
committed
feat(refs): unbind refs in collections items when collection is unbound
1 parent 8585086 commit 60f7487

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/index.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,14 @@ function bindCollection ({
6767
const originalResolve = resolve
6868
let isResolved
6969

70+
// contain ref subscriptions of objects
71+
// arraySubs is a mirror of array
72+
const arraySubs = []
73+
7074
const change = {
7175
added: ({ newIndex, doc }) => {
72-
const subs = {}
76+
arraySubs.splice(newIndex, 0, Object.create(null))
77+
const subs = arraySubs[newIndex]
7378
const snapshot = createSnapshot(doc)
7479
const [data, refs] = extractRefs(snapshot)
7580
array.splice(newIndex, 0, data)
@@ -94,8 +99,7 @@ function bindCollection ({
9499
}
95100
}
96101

97-
// TODO return custom unbind function that unbinds nested refs
98-
return collection.onSnapshot(({ docChanges }) => {
102+
const unbind = collection.onSnapshot(({ docChanges }) => {
99103
// console.log('pending', metadata.hasPendingWrites)
100104
// docs.forEach(d => console.log('doc', d, '\n', 'data', d.data()))
101105
// NOTE this will only be triggered once and it will be with all the documents
@@ -128,6 +132,15 @@ function bindCollection ({
128132
// resolves when array is empty
129133
if (!docChanges.length) resolve()
130134
}, reject)
135+
136+
return () => {
137+
unbind()
138+
arraySubs.forEach(subs => {
139+
for (const subKey in subs) {
140+
subs[subKey].unbind()
141+
}
142+
})
143+
}
131144
}
132145

133146
function updateDataFromDocumentSnapshot ({ snapshot, target, key, subs, depth = 0, resolve }) {

test/refs-collections.spec.js

+21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
tick,
55
delay,
66
delayUpdate,
7+
spyUnbind,
78
Vue
89
} from './helpers'
910

@@ -67,3 +68,23 @@ test('binds refs when adding to collection', async () => {
6768
{ ref: { isC: true }}
6869
])
6970
})
71+
72+
test('unbinds refs when the collection is unbound', async () => {
73+
const items = db.collection()
74+
const spyA = spyUnbind(a)
75+
const spyB = spyUnbind(b)
76+
await items.add({ ref: a })
77+
await items.add({ ref: b })
78+
await vm.$bind('items', items)
79+
80+
expect(spyA).toHaveBeenCalledTimes(0)
81+
expect(spyB).toHaveBeenCalledTimes(0)
82+
83+
vm.$unbind('items')
84+
85+
expect(spyA).toHaveBeenCalledTimes(1)
86+
expect(spyB).toHaveBeenCalledTimes(1)
87+
88+
spyA.mockRestore()
89+
spyB.mockRestore()
90+
})

test/refs-documents.spec.js

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ beforeEach(async () => {
3838
}
3939
})
4040
await tick()
41-
// NOTE should add option for it waitForRefs: true (by default)
4241
// wait for refs to be ready as well
4342
await delay(5)
4443
})

0 commit comments

Comments
 (0)