Подпишитесь на документ, используя Svelte / RxJs / RxFire. Как я могу обновить подписку - PullRequest
0 голосов
/ 12 ноября 2019

Я использую производное хранилище в коде ниже. Это похоже на странную конструкцию, потому что я использую производную конструкцию только для динамической зависимости $ session и для получения normData. Но не с $ нормой. Я использую $ norm только один раз, чтобы запустить производное хранилище.

Тем не менее, оно работает нормально. Но я должен возобновить подписку, если $ сеанс изменится. Можно ли обновить подписку 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 в реальном$ норма Магазин стройных вещей. Код ниже в моем собственном ответе.

Но реальный вопрос: могу ли я обновить подписку. Изменить подписку без отписки?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2019

У меня уже был ответ, но я его не осознавал.

Ниже производного кода магазина с опциями 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) {
    normSubscription.unsubscribe();
  }
});
0 голосов
/ 12 ноября 2019

Хорошо, примерно получите то, что вы пытаетесь описать здесь.

На самом деле вы можете использовать реактивное объявление для выполнения кода при изменении переменной / хранилища.

В этом случае необходимо выполнить метод повторной подписки:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...