需求
今天有这么一个需求:每一分钟调用一次后台接口,并且监听是在存在告警状态的设备,不论当前处在哪个页面,如果发现有设备处于告警状态,页面中间出现一个提示“xxx温度超过最高临界值”的弹窗,然后用户可以点击弹窗的确认按钮,跳转查看所有的告警设备。
难点是我们不知道用户当前处于哪个页面,但是仔细一想,我们可以去参考一下Ant Design Message组件,所以我们上github看一下 Message源码:
可以看出来Message是基于rc-notification包实现的,然后我们再看一下rc-notification文档,文档写的很清楚,也有使用方法:
// content是React.Element类型
var Notification = require('rc-notification');
Notification.newInstance({}, notification => {
notification.notice({
content: 'content'
});
});如果想要进一步了解notification是怎么实现可以在任意地方调用其函数就能够生成一个组件的,可以参考 这里。
我的项目是使用的Antd Design Pro框架的,下面来展示一下我的实现:
安装
npm install rc-notification组件
/src/components/TemperatureWarning
import { ConfirmModal } from '@/components/modal';
import Notification from 'rc-notification';
let notification = null;
Notification.newInstance({}, n => (notification = n));
const showModal = (data, callback) => {
// ConfirmModal是我封装的提示框组件
const content = ConfirmModal(
() => {
callback();
},
'温度告警',
'确定',
);
notification.notice({
content,
});
};
export { showModal };model
import { pathMatchRegexp } from './../utils/utils';
import { netboxNotice } from '@/services/api/app';
import { showModal } from '@/components/TemperatureWarning';
export default {
namespace: 'app',
state: {
existNotice: false, noticeData: [], },
subscriptions: {
// subscriptions是在app.start() 时被执行,setup是自定义的名字
setup({ dispatch }) {
dispatch({ type: 'queryNotice' });
setInterval(() => {
dispatch({ type: 'queryNotice' }); }, 1000 * 60);
},
},
effects: {
*queryNotice({ payload }, { call, put, select }) {
// 如果在根目录/登录页 不发起请求
if (pathMatchRegexp(['/', '/user/login'], window.location.pathname)) {
return;
}
// 温度预警
const existNotice = yield select(state => {
return state.app.existNotice;
});
let res = {};
if (!existNotice) {
res = yield call(netboxNotice);
}
if (res.data && res.data.length > 0) {
yield put({
type: 'showNoticeReducers',
payload: res.data,
});
}
},
},
reducers: {
showNoticeReducers(state, { payload }) {
return {
...state,
existNotice: true,
noticeData: payload,
};
},
hiddenNoticeReducers(state, { payload }) {
return {
...state,
existNotice: false,
};
},
},
};page
/src/layouts/BasicLayout.js
static getDerivedStateFromProps(nextProps, prevState) {
const { showNotice, dispatch, noticeData } = nextProps;
if (showNotice) {
temperatureWarning.showModal(noticeData, () => {
// 这里是弹窗确认按钮的回调处理函数,逻辑管理完之后关闭弹窗
// do something...
dispatch({ type: 'app/hiddenNoticeReducers'
});
});
return;
}
return null;
}