ExtJS 7 y Spring Boot 2. 驴C贸mo construir un SPA que interact煤e con su API y complementos externos de ReactJS?

Las versiones recientes de Ext JS, especialmente Modern Toolkit, redujeron el umbral para ingresar al marco (ejemplos de Kitchen Sink), simplificaron la creaci贸n de la interfaz deseada (hola Sencha Architect) y lograron un tama帽o m铆nimo de aplicaciones web (Sencha Cmd).

Quiz谩s, Habr deber铆a diluirse con un ejemplo de la implementaci贸n de un "centro situacional", en el que en tiempo real puede ver c谩maras y eventos desde ellos (todos los datos son falsos).



Empecemos Creemos un proyecto Spring Boot con 2 controladores que proporcionar谩n una lista de c谩maras, eventos existentes, as铆 como la posibilidad de suscribirse a nuevos eventos (a trav茅s de WebSocket).


A continuaci贸n, agregue los modelos necesarios, almacenamientos, vistas y dependencias externas:



Con m谩s detalle, la vista del mapa interact煤a con el componente Reaccionar del mapa.
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); } } }); 


Tambi茅n estamos de acuerdo en que los eventos vendr谩n del componente CamerasGrid, como Es este componente el responsable de agregar / quitar c谩maras de la tarjeta.

Controlador de componente CamerasGrid que agrega generaci贸n de eventos al componente
 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); } } } } }); 


El resultado es una interfaz bastante entretenida. Observo que con un dise帽o adecuado de la arquitectura de la aplicaci贸n (incluso una peque帽a), el tiempo para crear una es muy peque帽o, hasta un par de horas.



El c贸digo de muestra est谩 disponible en github.com .

Source: https://habr.com/ru/post/479676/


All Articles