使用 Svelte / RxJs / RxFire 订阅文档。如何更新订阅
Subscribe to a doc using Svelte / RxJs / RxFire. How can I update the subscription
我在下面的代码中使用了派生商店。这感觉像是一个奇怪的构造,因为我只使用派生构造来获取动态 $session 依赖项并获取 normData。但不是 $norm。我只使用 $norm 一次来启动派生存储。
尽管如此,它似乎工作正常。但如果 $session 发生变化,我必须续订订阅。是否可以在不先取消订阅的情况下更新 RxFire / RxJs 订阅?
let normDocRef = null;
let normData = null;
let normSubscription = null;
const norm = derived(
session,
$session => {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
// renew the subscription if $session changes
if (normSubscription)
normSubscription.unsubscribe();
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
normData = snapshot.data();
} else {
normData = null;
};
});
},
);
$norm; // kick off the derived store to monitor $session
// show the data and updates
$: console.log(normData);
onDestroy(() => {
if (normSubscription) normSubscription.unsubscribe();
});
Update:我可以使用派生商店的 set 和 return 选项来更改真正的 $norm Svelte 商店中的 $norm。下面的代码在我自己的回答中。
但真正的问题是:我可以更新订阅吗?更改订阅而不取消订阅?
好的,大致了解您要在此处描述的内容。
您实际上可以使用 reactive declaration 在变量/存储更改时执行代码。
本例是执行重新订阅方法:
let normDocRef = null;
let normData = null;
let normSubscription = null;
$: {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
// renew the subscription if $session changes
if (normSubscription) {
normSubscription.unsubscribe();
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
normData = snapshot.data();
} else {
normData = null;
};
});
}
}
onDestroy(() => {
if (normSubscription) normSubscription.unsubscribe();
});
这里的关键是,在编译时,Svelte 知道该块依赖于 $session
,因此只要 $session
发生变化,它就会重新执行代码块。
如果您想将其重构为另一个函数,您需要确保 Svelte 知道该函数依赖于 $session
,即:
$: resubscribe_norm($session);
在这里,Svelte 可以判断,如果 $session
改变了,需要再次调用 resubscribe_norm
。
我已经有了答案,只是没有意识到。
在带有 set() 和 return() 选项的派生商店代码下方。
当会话更改时,return() 将自动取消订阅。
所以仍然是取消订阅而不是更新......但这感觉很好。不错!
let normDocRef = null;
let normSubscription = null
const norm = derived(
session,
($session, set) => {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
set(snapshot.data());
} else {
set({}); // clear
};
});
return () => {
normSubscription.unsubscribe();
};
}, {} // initial value
);
$: console.log('$norm', $norm); // Now it is a real store
onDestroy(() => {
if (!normSubscription.closed) {
normSubscription.unsubscribe();
}
});
API docs 衍生商店:
从一个或多个其他商店派生商店。每当这些依赖项发生变化时(如 $session),回调就会运行。
如果您从回调中 "return a function",它将被调用(在回调之前)当 a) 回调再次运行时(因为依赖关系改变), 或 b) ...
我在下面的代码中使用了派生商店。这感觉像是一个奇怪的构造,因为我只使用派生构造来获取动态 $session 依赖项并获取 normData。但不是 $norm。我只使用 $norm 一次来启动派生存储。
尽管如此,它似乎工作正常。但如果 $session 发生变化,我必须续订订阅。是否可以在不先取消订阅的情况下更新 RxFire / RxJs 订阅?
let normDocRef = null;
let normData = null;
let normSubscription = null;
const norm = derived(
session,
$session => {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
// renew the subscription if $session changes
if (normSubscription)
normSubscription.unsubscribe();
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
normData = snapshot.data();
} else {
normData = null;
};
});
},
);
$norm; // kick off the derived store to monitor $session
// show the data and updates
$: console.log(normData);
onDestroy(() => {
if (normSubscription) normSubscription.unsubscribe();
});
Update:我可以使用派生商店的 set 和 return 选项来更改真正的 $norm Svelte 商店中的 $norm。下面的代码在我自己的回答中。
但真正的问题是:我可以更新订阅吗?更改订阅而不取消订阅?
好的,大致了解您要在此处描述的内容。
您实际上可以使用 reactive declaration 在变量/存储更改时执行代码。
本例是执行重新订阅方法:
let normDocRef = null;
let normData = null;
let normSubscription = null;
$: {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
// renew the subscription if $session changes
if (normSubscription) {
normSubscription.unsubscribe();
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
normData = snapshot.data();
} else {
normData = null;
};
});
}
}
onDestroy(() => {
if (normSubscription) normSubscription.unsubscribe();
});
这里的关键是,在编译时,Svelte 知道该块依赖于 $session
,因此只要 $session
发生变化,它就会重新执行代码块。
如果您想将其重构为另一个函数,您需要确保 Svelte 知道该函数依赖于 $session
,即:
$: resubscribe_norm($session);
在这里,Svelte 可以判断,如果 $session
改变了,需要再次调用 resubscribe_norm
。
我已经有了答案,只是没有意识到。
在带有 set() 和 return() 选项的派生商店代码下方。
当会话更改时,return() 将自动取消订阅。
所以仍然是取消订阅而不是更新......但这感觉很好。不错!
let normDocRef = null;
let normSubscription = null
const norm = derived(
session,
($session, set) => {
normDocRef = db.doc(`uploads/${$session.a_id}_${$session.year}`);
normSubscription = doc(normDocRef).subscribe(snapshot => {
if (snapshot.exists) {
set(snapshot.data());
} else {
set({}); // clear
};
});
return () => {
normSubscription.unsubscribe();
};
}, {} // initial value
);
$: console.log('$norm', $norm); // Now it is a real store
onDestroy(() => {
if (!normSubscription.closed) {
normSubscription.unsubscribe();
}
});
API docs 衍生商店:
从一个或多个其他商店派生商店。每当这些依赖项发生变化时(如 $session),回调就会运行。
如果您从回调中 "return a function",它将被调用(在回调之前)当 a) 回调再次运行时(因为依赖关系改变), 或 b) ...