Electron - tworzenie własnego prostego routingu i zmiana widoku w ramach jednego okna

Stronę tą wyświetlono już: 208 razy

Czas zrobić sobie prosty routing by z najdzikszą rozkoszą przełączać widok aplikacji w ramach jednego okna! Coby dłużej nie marnować czasu oto kod klasy, którą w tym jakże niecnym celu wykorzystuję do zrealizowania zadania routingu:

Listing 1
  1. const electron = require("electron");
  2. class RouteItem {
  3. path = "";
  4. viewClass;
  5. viewFile = "";
  6. children = new Array();
  7. constructor(
  8. path = "",
  9. viewClass = null,
  10. viewFile = "",
  11. children = new Array()
  12. ) {
  13. this.path = path;
  14. this.viewClass = viewClass;
  15. this.viewFile = viewFile;
  16. this.children = children;
  17. }
  18. changePath(path = new Array()) {
  19. let pathCopy = [...path];
  20. if (path.length) {
  21. const pathItem = pathCopy.shift();
  22. if (pathItem === this.path) {
  23. if (pathCopy.length) {
  24. if (this.children.length) {
  25. for (let i = 0; i < this.children.length; i++) {
  26. const returned = this.children[i].changePath(pathCopy);
  27. if (returned) {
  28. return returned;
  29. }
  30. }
  31. return false;
  32. }
  33. return false;
  34. }
  35. return this;
  36. }
  37. return false;
  38. }
  39. }
  40. }
  41. class Routing {
  42. routes = new Array();
  43. wnd;
  44. constructor(wnd, routes = new Array()) {
  45. this.routes = routes;
  46. this.wnd = wnd;
  47. }
  48. changeRoute(path = "") {
  49. const tablePath = path.split("/");
  50. for (let i = 0; i < this.routes.length; i++) {
  51. const returned = this.routes[i].changePath(tablePath);
  52. if (returned) {
  53. this.wnd.loadFile(returned.viewFile);
  54. return returned;
  55. }
  56. }
  57. return null;
  58. }
  59. }
  60. module.exports.RouteItem = RouteItem
  61. module.exports.Routing = Routing

Klasa RouteItem opisuje obiekt ścieżki routingu. Z kolei klasa Routing przeznaczona jest do obsługi przełączania widoku. Samo utworzenie ścieżek routingu w pliku index.js wygląda następująco:

Listing 2
  1. winRouting = new Routing(win , [
  2. new RouteItem('home', null, './index.html', [
  3. new RouteItem('subRouting', null, './sub-routing-view.html')
  4. ]),
  5. new RouteItem('trussCalculator', null, './truss-calculator.html', [])
  6. ])

Powyższy kod umieszczony został w funkcji tworzącej okno programu. Warto nadmienić, że konieczna będzie obsługa komunikatu przychodzącego na żądanie zmiany ścieżki:

Listing 3
  1. ipcMain.on(
  2. 'change-win-route',
  3. (e, routePath) => {
  4. console.log(routePath);
  5. winRouting.changeRoute(routePath)
  6. }
  7. )

w pliku index.js należy zaimportować obiekt ipcMain w następujący sposób:

Listing 4
  1. const { app, BrowserWindow, Menu, ipcMain } = require("electron");

Teraz w pliku index.html trzeba dodać parę przycisków:

Listing 5
  1. <button id="truss-calculator">Truss calculator</button>
  2. <button id="sub-routing">Podstrona</button>

A następnie w pliku index-view.js:

Listing 6
  1. const trussCalculator = document.querySelector("#truss-calculator");
  2. const subuRouting = document.querySelector("#sub-routing");
  3. trussCalculator.addEventListener(
  4. "click",
  5. () => {
  6. if (newViewWindow) {
  7. newViewWindow.close()
  8. newViewWindow = null;
  9. }
  10. ipcRenderer.send('change-win-route', 'trussCalculator');
  11. }
  12. )
  13. subuRouting.addEventListener(
  14. "click",
  15. () => {
  16. if (newViewWindow) {
  17. newViewWindow.close()
  18. newViewWindow = null;
  19. }
  20. ipcRenderer.send('change-win-route', 'home/subRouting');
  21. }
  22. )

Stworzyłem do celów pokazowych dwa dodatkowe widoki, jeden w pliku truss-calculator.html:

Listing 7
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>Truss calculator</title>
  6. <meta
  7. http-equiv="Content-Security-Policy"
  8. content="script-src 'self' 'unsafe-inline';"
  9. />
  10. <script src="./viewscripts/truss-calculator-view.js"></script>
  11. <style>
  12. </style>
  13. </head>
  14. <body style="background: white">
  15. <div>
  16. <h2>Welcome to Pyrry</h2>
  17. <button id="home">Home</button>
  18. </div>
  19. <iframe src="https://obliczeniowo.com.pl/Angular_examples/TrussCalculator" width="100%" height="800" ></webview>
  20. </body>
  21. </html>

I drugi w pliku sub-routing-view.html:

Listing 8
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>Truss calculator</title>
  6. <meta
  7. http-equiv="Content-Security-Policy"
  8. content="script-src 'self' 'unsafe-inline';"
  9. />
  10. <script src="./viewscripts/truss-calculator-view.js"></script>
  11. <style>
  12. </style>
  13. </head>
  14. <body style="background: white">
  15. <div>
  16. <h2>Sub routing</h2>
  17. <button id="home">Home</button>
  18. </div>
  19. </body>
  20. </html>

Dodałem też jeden plik z skryptem truss-calculator-view.js:

Listing 9
  1. /**
  2. * import ipcRenderer-a umożliwiającego wysyłanie informacji
  3. */
  4. const ipcRenderer = require("electron").ipcRenderer;
  5. const electron = require("electron");
  6. let newViewWindow = undefined;
  7. window.addEventListener("load", () => {
  8. const btHome = document.querySelector("#home");
  9. btHome.addEventListener(
  10. "click",
  11. () => {
  12. if (newViewWindow) {
  13. newViewWindow.close()
  14. newViewWindow = null;
  15. }
  16. ipcRenderer.send('change-win-route', 'home');
  17. }
  18. )
  19. const webview = document.querySelector('webview')
  20. const indicator = document.querySelector('.indicator')
  21. const loadstart = () => {
  22. indicator.innerText = 'loading...'
  23. }
  24. const loadstop = () => {
  25. indicator.innerText = ''
  26. }
  27. webview.addEventListener('did-start-loading', loadstart)
  28. webview.addEventListener('did-stop-loading', loadstop)
  29. });

Teraz po uruchomieniu programu będzie można przełączać się pomiędzy widokami.

Strony powiązane
strony powiązane
  1. github.com/Obliczeniowo/Electron-basic-project - gałąź repozytorium zawierająca kod umożliwiający przełączanie widoku okna

Komentarze