ExtJS 7和Spring Boot2。如何构建与您的API和外部ReactJS插件交互的SPA?

Ext JS的最新版本,尤其是Modern Toolkit,降低了进入框架的门槛(例如Kitchen Sink),简化了所需界面的创建(hi Sencha Architect),并实现了最小的Web应用程序大小(Sencha Cmd)。

也许,应该以“情景中心”的实施示例来简化Habr,在该情景中,您可以实时观看摄像机和其中的事件(所有数据都是伪造的)。



让我们开始吧。 让我们用2个控制器创建一个Spring Boot项目,该项目将提供摄像机列表,现有事件以及通过WebSocket订阅新事件的功能。


接下来,添加必要的模型,存储,视图和外部依赖项:



更详细地讲,地图视图与地图的React组件进行交互。
Ext.define('Cameras.view.override.Map', { override: 'Cameras.view.Map', config: { cameras: {}, react: null }, initialize: function() { let that = this; let e = React.createElement; this.setReact(ReactDOM.render(e(createReactClass({ getInitialState: function() { return { items: [], center: [55.751574, 37.573856]}; }, render: function() { let placemarks = []; for(let i=0; i < this.state.items.length; i++) { let location = this.state.items[i].get("location"); placemarks.push(e(window.ReactYandexMaps.Placemark, { geometry: [location.latitude, location.longitude], options: { preset: 'islands#blueCircleDotIconWithCaption', iconCaptionMaxWidth: '50' } })); } let map = e(window.ReactYandexMaps.Map, { state: { center: this.state.center, zoom: 10 }, width: '100%', height: '100%' }, placemarks); return e(window.ReactYandexMaps.YMaps, null, map); } })), this.mapContainer.dom)); }, getElementConfig: function() { return { reference: 'element', className: 'x-container', children: [{ reference: 'bodyElement', style: 'width: 100%; height: 100%', className: 'x-inner', children: [{ style: 'width: 100%; height: 100%', reference: 'mapContainer', className: Ext.baseCSSPrefix + 'map-container' }] }] }; }, addCamera: function(cameraModel) { if(!this.containsCamera(cameraModel)) { this.getCameras()[cameraModel.get("id")] = cameraModel; this.getReact().setState({ items: Object.values(this.getCameras()) }); this.fitCamera(cameraModel); } }, removeCamera: function(cameraModel) { if(this.containsCamera(cameraModel)) { delete this.getCameras()[cameraModel.get("id")]; this.getReact().setState({ items: Object.values(this.getCameras()) }); } }, fitCamera: function(cameraModel) { if(this.containsCamera(cameraModel)) { let location = this.getCameras()[cameraModel.get("id")].get("location"); this.getReact().setState({ center: [location.latitude, location.longitude] }); } }, privates: { containsCamera: function(cameraModel) { cameraId = "" + cameraModel.get("id"); return Object.keys(this.getCameras()).includes(cameraId); } } }); 


我们还同意事件将来自CamerasGrid组件,因为 正是这个组件负责从卡中添加/删除相机。

CamerasGrid组件控制器,将事件生成添加到组件
 Ext.define('Cameras.view.CamerasGridViewController', { extend: 'Ext.app.ViewController', alias: 'controller.camerasgrid', init: function() { let socket = new WebSocket("ws://localhost:8080/events/sub"); socket.onopen = function(e) { console.log('onopen'); }; socket.onmessage = this.onMessage.bind(this); }, onMessage: function(event) { let data = Ext.decode(event.data); let gridData = this.getView().getStore().getData(); for(let i=0; i < gridData.length; i++) { let checked = gridData.getAt(i).get("checked"); if(checked !== undefined && checked) { if(gridData.getAt(i).get("id") == data.camera.id) { this.fireViewEvent("cameraRecognition", data); } } } } }); 


结果是一个相当有趣的界面。 我注意到,通过对应用程序体系结构进行适当的设计(甚至很小),创建一个应用程序的时间非常少,最多需要几个小时。



示例代码可在github.com找到

Source: https://habr.com/ru/post/zh-CN479676/


All Articles