mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: websocket 支持设置初始提交数据 (#2766)
This commit is contained in:
parent
ed92a2b1be
commit
ad0d941031
@ -345,7 +345,6 @@ Service 支持通过 WebSocket 获取数据,只需要设置 ws(由于无示
|
||||
```json
|
||||
{
|
||||
"type": "service",
|
||||
"api": "/api/mock2/page/initData",
|
||||
"ws": "ws://localhost:8777",
|
||||
"body": {
|
||||
"type": "panel",
|
||||
@ -355,6 +354,30 @@ Service 支持通过 WebSocket 获取数据,只需要设置 ws(由于无示
|
||||
}
|
||||
```
|
||||
|
||||
> 1.3.5 及以上版本
|
||||
|
||||
或者是对象的方式支持配置初始 `data`,这个 data 会在建立连接时发送初始数据
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "service",
|
||||
"ws": {
|
||||
"url": "ws://localhost:8777?name=${name}",
|
||||
"data": {
|
||||
"name": "${name}"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
{
|
||||
"label": "名称",
|
||||
"type": "input-text",
|
||||
"value": "name",
|
||||
"name": "amis"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以只设置 ws,通过 ws 来获取所有数据,也可以同时设置 api 和 ws,让 api 用于获取全部数据,而 ws 用于获取实时更新的数据。
|
||||
|
||||
后端实现示例,基于 [ws](https://github.com/websockets/ws):
|
||||
@ -379,11 +402,18 @@ ws.on('connection', function connection(ws) {
|
||||
|
||||
WebSocket 客户端的默认实现是使用标准 WebSocket,如果后端使用定制的 WebSocket,比如 socket.io,可以通过覆盖 `env.wsFetcher` 来自己实现数据获取方法,默认实现是:
|
||||
|
||||
> 1.3.5 及以上版本修改了 ws 类型,将之前的字符串改成了对象的方式,会有两个参数 url 和 body
|
||||
|
||||
```javascript
|
||||
wsFetcher(ws, onMessage, onError) {
|
||||
if (ws) {
|
||||
const socket = new WebSocket(ws);
|
||||
socket.onmessage = (event: any) => {
|
||||
const socket = new WebSocket(ws.url);
|
||||
socket.onopen = event => {
|
||||
if (ws.body) {
|
||||
socket.send(JSON.stringify(ws.body));
|
||||
}
|
||||
};
|
||||
socket.onmessage = event => {
|
||||
if (event.data) {
|
||||
onMessage(JSON.parse(event.data));
|
||||
}
|
||||
|
@ -74,11 +74,16 @@ export interface RenderSchemaFilter {
|
||||
(schema: Schema, renderer: RendererConfig, props?: any): Schema;
|
||||
}
|
||||
|
||||
export interface wsObject {
|
||||
url: string;
|
||||
body?: any;
|
||||
}
|
||||
|
||||
export interface RenderOptions {
|
||||
session?: string;
|
||||
fetcher?: (config: fetcherConfig) => Promise<fetcherResult>;
|
||||
wsFetcher?: (
|
||||
ws: string,
|
||||
ws: wsObject,
|
||||
onMessage: (data: any) => void,
|
||||
onError: (error: any) => void
|
||||
) => void;
|
||||
@ -234,8 +239,13 @@ const defaultOptions: RenderOptions = {
|
||||
// 使用 WebSocket 来实时获取数据
|
||||
wsFetcher(ws, onMessage, onError) {
|
||||
if (ws) {
|
||||
const socket = new WebSocket(ws);
|
||||
socket.onmessage = (event: any) => {
|
||||
const socket = new WebSocket(ws.url);
|
||||
socket.onopen = event => {
|
||||
if (ws.body) {
|
||||
socket.send(JSON.stringify(ws.body));
|
||||
}
|
||||
};
|
||||
socket.onmessage = event => {
|
||||
if (event.data) {
|
||||
onMessage(JSON.parse(event.data));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import {filter, evalExpression} from '../utils/tpl';
|
||||
import cx from 'classnames';
|
||||
import Scoped, {ScopedContext, IScopedContext} from '../Scoped';
|
||||
import {observer} from 'mobx-react';
|
||||
import {isApiOutdated, isEffectiveApi} from '../utils/api';
|
||||
import {buildApi, isApiOutdated, isEffectiveApi} from '../utils/api';
|
||||
import {Spinner} from '../components';
|
||||
import {autobind, isEmpty, isVisible, qsstringify} from '../utils/helper';
|
||||
import {
|
||||
@ -168,7 +168,7 @@ export default class Service extends React.Component<ServiceProps> {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
this.socket = store.fetchWSData(props.ws, this.afterDataFetch);
|
||||
this.socket = this.fetchWSData(props.ws, store.data);
|
||||
}
|
||||
|
||||
if (props.defaultData !== prevProps.defaultData) {
|
||||
@ -216,10 +216,39 @@ export default class Service extends React.Component<ServiceProps> {
|
||||
}
|
||||
|
||||
if (ws) {
|
||||
this.socket = store.fetchWSData(ws, this.afterDataFetch);
|
||||
this.socket = this.fetchWSData(ws, store.data);
|
||||
}
|
||||
}
|
||||
|
||||
// 因为有异步,这里
|
||||
fetchWSData(ws: string | Api, data: any) {
|
||||
const {env, store} = this.props;
|
||||
const wsApi = buildApi(ws, data);
|
||||
|
||||
env.wsFetcher(
|
||||
wsApi,
|
||||
(data: any) => {
|
||||
let returndata = data;
|
||||
if ('status' in data && 'data' in data) {
|
||||
returndata = data.data;
|
||||
if (data.status !== 0) {
|
||||
store.updateMessage(data.msg, true);
|
||||
env.notify('error', data.msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
store.updateData(returndata, undefined, false);
|
||||
store.setHasRemoteData();
|
||||
// 因为 WebSocket 只会获取纯数据,所以没有 msg 之类的
|
||||
this.afterDataFetch({ok: true, data: returndata});
|
||||
},
|
||||
(error: any) => {
|
||||
store.updateMessage(error, true);
|
||||
env.notify('error', error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
afterDataFetch(result: any) {
|
||||
// todo 应该统一这块
|
||||
// 初始化接口返回的是整个 response,
|
||||
|
@ -140,24 +140,6 @@ export const ServiceStore = iRendererStore
|
||||
}
|
||||
});
|
||||
|
||||
const fetchWSData = (ws: string, afterDataFetch: (data: any) => any) => {
|
||||
const env = getEnv(self);
|
||||
|
||||
env.wsFetcher(
|
||||
ws,
|
||||
(data: any) => {
|
||||
self.updateData(data, undefined, false);
|
||||
setHasRemoteData();
|
||||
// 因为 WebSocket 只会获取纯数据,所以没有 msg 之类的
|
||||
afterDataFetch({ok: true, data: data});
|
||||
},
|
||||
(error: any) => {
|
||||
updateMessage(error, true);
|
||||
env.notify('error', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const setHasRemoteData = () => {
|
||||
self.hasRemoteData = true;
|
||||
};
|
||||
@ -505,7 +487,6 @@ export const ServiceStore = iRendererStore
|
||||
markBusying,
|
||||
fetchInitData,
|
||||
fetchData,
|
||||
fetchWSData,
|
||||
reInitData,
|
||||
updateMessage,
|
||||
clearMessage,
|
||||
|
Loading…
Reference in New Issue
Block a user