美文网首页
使用控制器进行数据派发,实现页面实时更新

使用控制器进行数据派发,实现页面实时更新

作者: 静静_5835 | 来源:发表于2021-10-08 11:02 被阅读0次

    1. 项目使用:数据大屏

    2. 使用场景

    • 封装派发器,定时对页面进行数据派发,页面根据接收到的数据,进行实时更新,实现炫酷效果

    3. 实现效果

    • 显示单个组件的控制器场景(控制器下可能有N个组件,但是同时只展示单个组件)


      在这里插入图片描述
    • 显示列表组件的控制器场景(列表恒定只展示10条数据,每新增一条就需要移除一条)


      在这里插入图片描述

    4. 代码结构

    在这里插入图片描述

    5. bean.ts代码

    // 接口数据请求定义
    export enum DataTypeCode {
        UserSituation = 'UserSituation'
    }
    
    // 派发的数据结构
    export class DataBo {
        data: []
    }
    
    // 派发回调
    export interface IDispatchCallback {
        (data: any[]):void
    }
    
    // 数据派发器参数
    export class Options {
    
        //首次派发数据量
        firstDispatch: number
    
        //非首次派发数据量
        nextDispatch: number
    
        //是否循环派发
        loop?: boolean = true
    
        // 派发数据类型
        dataType: DataTypeCode
    
        // 循环派发时间 秒
        loopTime?: number = 1
    
        //派发回调函数
        callback: IDispatchCallback
    
        key?: string
        // 重新派发?
        noRepeatDispatch?: boolean = false
    }
    
    export interface totalData {
        dayNum: number
        weekNum: number
    }
    
    export declare class DataProvider<T> {
        /**
         * 数据
         */
        private data;
        /**
         * promise队列,用于后续回调
         */
        private promises;
        /**
         * 异步获取信息
         * @returns
         */
        getData(): Promise<T>;
        /**
         * @param data
         */
        setData(data: T): void;
        /**
         * 是否准备好回调
         * @returns
         */
        protected isReady(): boolean;
        /**
         * 获取data对象
         * @returns
         */
        protected getObj(): T;
        private handle;
    }
    
    

    6. data-dispatch 控制器代码

    import { Options } from './bean'
    
    export class Dispatch {
    
        //配置信息
        private opts: Options
    
        //需要派发的数据,如果loop=true,在派发完后会重新派发
        private data: any
    
        private dispatchData: any[]
    
        private timer
    
        constructor(opts: Options) {
            clearTimeout(this.timer)
            //TODO 可以初始化的时候,传入callback
            this.opts = opts
        }
    
        // 调用start即开始派发数据
        // 数据中心定时刷新数据以后,只需要调用start,即可刷新data,重新派发数据
        start(data: any[]):void {
            clearTimeout(this.timer)
            this.data = data
            // 派发数据为数组时
            if (Array.isArray(this.data)) {
                this.dispatchData = this.data.slice(0, this.opts.firstDispatch)
                this.timeoutDispatch(this.opts.firstDispatch)
            }
            // 派发数据为非数组时
            else {
                console.error('非数组数据无法进行派发')
            }
        }
    
        // 数据派发
        disPatch():void {
            this.opts.callback(this.dispatchData)
        }
    
        // 根据页面设置进行数据循环派发
        timeoutDispatch(num: number):void {
            this.disPatch()
            // 支持循环且数据长度大于首次派发数据长度,才支持循环派发
            if (!this.data || !this.data.length || (this.data.length <= this.opts.firstDispatch) || (num >= this.data.length && !this.opts.loop)) {
                return
            }
            this.timer = setTimeout(() => {
                num = num + 1
                // 数据长度超过实际长度,从新开始派发  或者根据字段noRepeatDispatch决定是否接着派发
                if (num > this.data.length) {
                    num = this.opts.noRepeatDispatch ? this.opts.nextDispatch : this.opts.firstDispatch
                }
                // num长度等于首次派发长度,派发数据量 = 首次派发数据量
                if (num === this.opts.firstDispatch && num !== 1) {
                    this.dispatchData = this.data.slice(0, this.opts.firstDispatch)
                }
                // 否则,按照 非首次派发数据量 进行派发
                else {
                    this.dispatchData = this.data.slice(num - this.opts.nextDispatch, num)
                }
                clearTimeout(this.timer)
                this.timeoutDispatch(num)
            }, this.opts.loopTime * 1000)
        }
    }
    

    7. data-center 数据中心代码

    import { Dispatch } from './data-dispatch'
    import { DataTypeCode, Options, totalData, DataProvider } from './bean'
    import api from '@/api/api'
    
    // 平台运营总量
    const getUserSituation = () => {
        return api.getUserSituation().then(res => {
            return Promise.resolve({ data: [res.data] })
        })
    }
    const dataApiMap = {}
    
    // 平台运营总量
    dataApiMap[DataTypeCode.UserSituation] = getUserSituation
    
    // 数据中心获取数据触发派发器
    export class DataCenter {
    
        private dispatch
    
        // 请求接口类型
        private type: DataTypeCode
    
        private timer
    
        constructor(opts: Options) {
            this.dispatch = new Dispatch(opts)
            clearTimeout(this.timer)
        }
    
        // 获取接口数据
        private getData() {
            dataApiMap[this.type]().then(res => {
                // 触发派发器
                this.dispatch.start(res.data)
            })
        }
    
        // 定时获取数据,每隔5分钟请求一次接口
        private initData(type: DataTypeCode) {
            clearTimeout(this.timer)
            this.type = type
            this.getData()
            this.timer = setTimeout(() => {
                clearTimeout(this.timer)
                this.initData(type)
            }, 5 * 60 * 1000)
        }
    }
    

    8. 页面中数据获取

    getData() {
        const options = {
             firstDispatch: 7,
             nextDispatch: 1,
             callback: (data) => {
                // 每隔一秒派发器会派发数据到页面,页面接收后,可以根据需要对数据进行处理
                  console.log(data)
             }
         }
         const data = new DataCenter(options)
         data.initData('UserSituation')
    }
    

    相关文章

      网友评论

          本文标题:使用控制器进行数据派发,实现页面实时更新

          本文链接:https://www.haomeiwen.com/subject/hbxxoltx.html