管理员休息 - 实现aor-realtime

问题描述 投票:0回答:2

我真的很难理解如何实现aor-realtime(尝试使用firebase;只读,不写)。

我遇到的第一个地方:这个库产生了一个传奇,对吧?如何将其与restClient /资源连接?我有一些自定义传奇警告我错误,但有一个主要的restClient /资源支持那些。那些传奇只是处理一些副作用。在这种情况下,我只是不明白客户端的角色是什么,以及它如何与生成的传奇交互(反之亦然)

另一个问题是持久性:更新流输入和初始记录集不会一次加载。我应该在每次更新时调用observer.next()吗?或者缓存更新的记录并使用整个集合调用next()到目前为止。

这是我目前尝试做的事情,但我仍然对如何将其连接到我的管理员/资源感到迷茫。

import realtimeSaga from 'aor-realtime';
import { client, getToken } from '../firebase';
import { union } from 'lodash'

let cachedToken 
const observeRequest = path => (type, resource, params) => {
    // Filtering so that only chats are updated in real time
    if (resource !== 'chat') return;

    let results = {}
    let ids = []

    return {
        subscribe(observer) {
            let databaseRef = client.database().ref(path).orderByChild('at')

            let events = [ 'child_added', 'child_changed' ]

            events.forEach(e => {
                databaseRef.on(e, ({ key, val }) => {
                    results[key] = val()
                    ids = union([ key ], ids)
                    observer.next(ids.map(id => results[id]))
                })  
            })          
            const subscription = {
                unsubscribe() {
                    // Clean up after ourselves
                    databaseRef.off()
                    results = {}
                    ids = []
                    // Notify the saga that we cleaned up everything
                    observer.complete();
                }
            };

            return subscription;
        },
    };
};

export default path => realtimeSaga(observeRequest(path));
admin-on-rest
2个回答
1
投票

如何将其与restClient /资源连接?

只需将创建的传奇添加到custom sagas组件的Admin即可。

关于restClient,如果你需要在观察者中使用它,那么将它传递给返回你的观察者的函数,就像你使用path一样。这实际上是在readme中完成的。

我应该在每次更新时调用observer.next()吗?或者缓存更新的记录并使用整个集合调用next()到目前为止。

它取决于type参数,它是admin-on-rest fetch类型之一:

  • CRUD_GET_LIST:你应该返回整个集合,更新
  • CRUD_GET_ONE:你应该返回params中指定的资源(应该包含它的id)

1
投票

这是我提出的解决方案,由@gildas指导:

import realtimeSaga from "aor-realtime";
import { client } from "../../../clients/firebase";
import { union } from "lodash";
const observeRequest = path => {      
  return (type, resource, params) => {
    // Filtering so that only chats are updated in real time
    if (resource !== "chats") return;

    let results = {}
    let ids = []

    const updateItem = res => {
      results[res.key] = { ...res.val(), id: res.key }
      ids = Object.keys(results).sort((a, b) => results[b].at - results[a].at)
    }

    return {
      subscribe(observer) {
        const { page, perPage } = params.pagination
        const offset = perPage * (page - 1)

        const databaseRef = client
            .database()
            .ref(path)
            .orderByChild("at")
            .limitToLast(offset + perPage)

        const notify = () => observer.next({ data: ids.slice(offset, offset + perPage).map(e => results[e]), total: ids.length + 1 })

        databaseRef.once('value', snapshot => {
          snapshot.forEach(updateItem)
          notify()
        })

        databaseRef.on('child_changed', res => {
          updateItem(res)
          notify()    
        })


        const subscription = {
          unsubscribe() {
            // Clean up after ourselves
            databaseRef.off();
            // Notify the saga that we cleaned up everything
            observer.complete();
          }
        };

        return subscription;
      }
    };
  }
};

export default path => realtimeSaga(observeRequest(path));
© www.soinside.com 2019 - 2024. All rights reserved.