使用Svelte/RxJs/RxFire订阅文档。如何更新订阅

使用Svelte/RxJs/RxFire订阅文档。如何更新订阅,rxjs,svelte,derived,rxfire,Rxjs,Svelte,Derived,Rxfire,我在下面的代码中使用派生存储。这感觉像是一个奇怪的构造,因为我只将派生构造用于动态$session依赖项并获取数据。但不是用$norm。我只使用$norm一次来启动派生存储 尽管如此,它似乎运作良好。但是如果$session发生变化,我必须续订。是否可以在不取消订阅的情况下更新RxFire/RxJs订阅 let normDocRef = null; let normData = null; let normSubscription = null; const norm = derived(

我在下面的代码中使用派生存储。这感觉像是一个奇怪的构造,因为我只将派生构造用于动态$session依赖项并获取数据。但不是用$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();
}); 
更新:我可以使用派生存储的set和return选项在真正的$norm苗条存储中更改$norm。下面是我自己的答案


但真正的问题是:我可以更新订阅吗。在不取消订阅的情况下更改订阅?

好的,大致了解您在这里试图描述的内容

当变量/存储发生更改时,实际上可以使用来执行代码

在这种情况下,要执行重新订阅方法:

让normDocRef=null;
设normData=null;
让normSubscription=null;
$: {
normDocRef=db.doc(`uploads/${$session.a_id}{$session.year}`);
//如果$session发生更改,请续订订阅
如果(正常订阅){
正常订阅。取消订阅();
normSubscription=doc(normDocRef).订阅(快照=>{
if(snapshot.exists){
normData=snapshot.data();
}否则{
normData=null;
};
});
}
}
onDestroy(()=>{
if(normSubscription)normSubscription.unsubscribe();
}); 
这里的关键是,在编译此代码时,Svelte知道代码块取决于
$session
,因此每当
$session
发生更改时,它都会重新执行代码块

如果要将其重构为另一个函数,则需要确保Svelte知道该函数依赖于
$session
,即:

$:重新订阅定额($session);

在这里,斯维特可以告诉你,如果
$session
发生了变化,需要再次致电
重新订阅规范。

我已经得到了答案,但没有意识到

下面是带有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();
  }
});
派生存储:

从一个或多个其他存储派生存储。只要这些依赖项发生更改(如$session),回调就会运行


如果您从回调中“返回一个函数”,则当a)回调再次运行(因为依赖关系已更改),或b)时(在回调之前)将调用该函数。

请纠正我如果我误解了您的问题,您希望在
会话
更改时重新订阅
normDocRef
?文档名称包含一年,2010年到2019年。因此,当我更改会话年时,我希望更新订阅。这不是问题所在。派生存储取决于会话,并将在会话更改时续订。它在我展示的代码中运行良好。这里没问题。但是是否可以更新订阅(查询)。无需取消订阅/订阅即可切换到其他文档。感谢您的回复。我也更新了问题。不清楚。不确定您在寻找什么,是否可以在不取消订阅的情况下更新订阅,这取决于
db.doc
,它不是来自svelte对吗?也许您可以反应性地声明
$:normDocRef=db.doc(`uploads/${$session.a_id}{$session.year})
,然后派生
norm
,而不是
$session
。因此,如果需要,您还可以手动更改
normDocRef