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

2021-10-08  本文已影响0人  静静_5835

1. 项目使用:数据大屏

2. 使用场景

3. 实现效果

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')
}
上一篇下一篇

猜你喜欢

热点阅读