ExtJS 7 et Spring Boot 2. Comment construire un SPA qui interagit avec votre API et les plugins ReactJS externes?

Les versions récentes d'Ext JS, en particulier la boîte à outils moderne, ont abaissé le seuil d'entrée dans le cadre (exemples d'évier de cuisine), simplifié la création de l'interface souhaitée (salut Sencha Architect) et atteint une taille minimale pour les applications Web (Sencha Cmd).

Peut-être, Habr devrait être dilué avec un exemple de mise en œuvre d'un «centre situationnel», où en temps réel, vous pouvez regarder des caméras et des événements à partir d'eux (toutes les données sont fausses).



Commençons. Créons un projet Spring Boot avec 2 contrôleurs qui donnera une liste des caméras, des événements existants, ainsi que la possibilité de s'abonner à de nouveaux événements (via WebSocket).


Ensuite, ajoutez les modèles, les stockages, les vues et les dépendances externes nécessaires:



Plus en détail, la vue de carte interagissant avec le composant React de la carte.
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); } } }); 


Nous convenons également que les événements proviendront du composant CamerasGrid, comme c'est ce composant qui est chargé d'ajouter / supprimer des caméras de la carte.

Contrôleur de composant CamerasGrid qui ajoute la génération d'événements au composant
 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); } } } } }); 


Le résultat est une interface plutôt divertissante. Je note qu'avec une conception correcte de l'architecture de l'application (même si petite), le temps pour en créer une est très petit, jusqu'à quelques heures.



Un exemple de code est disponible sur github.com .

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


All Articles