URL change based view loading

Hi Wizards of Webix,

I would like to ask for your wisdom with regards to webix-jet routing / referencing subviews, I am new to this and my background is in devops/ infrastructure automation, just thought that it would be cool to have a better understanding of SPAs and based on my research Webix is one of if not the best framework for that. I can’t seem to find any examples / wrap my head around the implementation of URL change based view loading, even after spending considerable amount of time testing and reading up on it.

I am trying to use make a sample basic app (index.ts) with a menu view (top.ts) which has subviews myview.ts/aboutview.ts. The code gets transpiled to ES5 using webpack-cli. The page loads, and when I click on one of the options the corresponding view is loaded. All good so-fare, however the problem is that when I try to load subview via browser addressbar (/top/myview or /top/aboutview) it only loads “/top” view and subview never gets loaded.

Looking at the documentation, I think the urlchange() method [1][2] needs to be invoked but not sure if that is the best way to do that and if so how to do it/ where can I find example code for that. Can someone please show me how is this done? Thank you.

References:
[1] Page not found - Webix Jet
[2] https://blog.webix.com/webix-jet-chronicles-whats-new/

Below you can see the “application” code.

index.ts:

import {JetApp, JetView,EmptyRouter } from "webix-jet";
import "../node_modules/webix/webix"; 
declare var require: any
import TopView from "./views/top" ;
import AboutView from "./views/aboutview" ;
webix.ready(() => {
	const app = new JetApp({

		start:		"/top/myview",
		// router: HashRouter,
		// routes:		{
		// 	"/x" 	: "/top/aboutview",
		// 	"/y" 	: "/top/myview"
		// },
		//router:		UrlRouter,
		//routerPrefix: configjson.routerPrefix,
		debug: true,

	});
	app.render();

	app.attachEvent("app:error:resolve", function(name:any, error:any){
		window.console.error(error);
	});
});

top.ts:

import {JetView} from "webix-jet";
export default class TopView extends JetView {
	config(){
		
		return {
			type:"space", cols:[
				{ view:"list", width: 200, select:true, data:[
				
					{ value:"Myview", id:"myview", route:"myview"},
					{ value:"About", id:"about", route:"aboutview"}
				], click:function(id){
					var item = this.getItem(id);
					this.$scope.show(item.route);
					console.log(item+"dd")
				}},
				{ $subview: true }
			]
		};

	}

		init(view, url){
			var id = url[1].page //this.getParam("id", true);
			//this.show(id.route);
			console.log(id)
    }
}

myview.ts:

import {JetView, plugins} from "webix-jet";

export default class MyView extends JetView{
	config(){
		return {
			template:"MyView text"
		};
	}
}

aboutview.ts:

import {JetView, plugins} from "webix-jet";

export default class AboutView extends JetView{
	config(){
		return {
			template:"About page"
		};
	}
}

Hi,

The same works for me, please check Code Snippet

I think the urlchange() method [1][2] needs to be invoked

When you are changing the URL, this method will be invoked, but you need not call it directly or even implement it to have subviews working.

If the issue still occurs for you, please try to change init code of the app similar to one from the snippet, so it will include the name - class relations.

const app = new JetApp({
  start:      "/top/myview",
  debug:true,
  views:{
    top: TopView, // <- here it is
    myview:MyView,
    aboutview:AboutView
  }
});

By default ( when “views” structure is not provided ) code will try to load class from “views/{viewname}”, which means for “/top/myview” it will load /views/top.ts and /views/myview.ts.

Also, by any chance, have you modified wepback / tsconfig for your project? ( webix-start repo has “typescript” branch with default configs for typescript based project ).

Hello Maxim, thank you so much for your suggestions! I want to thoroughly review and do tests. I will have time for that over the weekend, so I will get back to you on Monday with the results, thank you again. Cheers, pappgez

Hello Maksim, I trust you are well, I did the tests, and subview loading based on url change is not working unfortunatelly.

I think its has either something to do with the options I set for transpiling from .ts to .js or perhaps it might be bug in jet framework Typescript implementation.

What I did is commented out all of my code and used code from snippet, modified it only so that I don’t get warnings in VisualStudio code for example added to index.ts

import TopView from "./views/top" ;
import AboutView from "./views/aboutview" ;
import MyView from "./views/myview";

however the subview does not get loaded not at url change nor at initialisation, both times only the top view loads. The subviews are loaded when I click on the corresponding menu items.

Regarding your question about webpack/tsconfig settings, I somewhat modified both, for tsconfig I did tests with my config as well as commented all out and used configuration from typescript-demo/tsconfig.json at master · webix-hub/typescript-demo · GitHub as is, the issue persisted with both settings.

As for the webpackconfig please find current setting bellow:

var debug = process.env.NODE_ENV !== "production";
var path = require("path");
var webpack = require('webpack');

module.exports = {
  context: __dirname,
  watch: true,
  devtool: debug ? "inline-source-map" : false,
  mode: debug ? "development":"production",
  entry: "./sources/index.ts",
  output: {
    path: __dirname + "/build",
    filename: "index.min.js"
  },
  module: {
    rules: [
        { test: /\\.ts$/,  loader: 'awesome-typescript-loader' }
    ]
},
  plugins: debug ? [] : [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/)
  ],
  resolve: {
    extensions: [".ts", ".tsx", ".js"],   
    alias:{
      "jet-views":path.resolve(__dirname, "sources/views"),
      "jet-locales":path.resolve(__dirname, "sources/locales")
    }
  }
};

not sure if needed but in case it is, I am using Windows Server 2016, node v8.11.1, latest chrome, as for other settings, at the end you may find the content of packageconfig.json.
Please let me know if you have any suggestions on how to proceed.

{
  "name": "test-ui",
  "version": "0.0.3",
  "description": "test ui",
  "main": "/build/index.min.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tslint": "tslint sources/**/**/*.ts -p .\\tsconfig.json",
    "lintfix": "eslint --fix sources/",
    "dist": "node /build/index.min.js",
    "start": "webpack-cli ./sources/index.ts -o ./build/index.min.js"
  },
  "keywords": [
    "ui",
    "webix"
  ],
  "author": "pappgez",
  "license": "GPL-3.0",
  "dependencies": {
    "@types/es6-promise": "^3.3.0",
    "@types/npm": "^2.0.29",
    "lodash": "^4.17.5",
    "npm": "^6.0.1",
    "ts-lint": "^4.5.1",
    "typescript": "^2.8.3",
    "webix": "^5.2.1",
    "webix-jet": "^1.4.1",
    "webpack": "^4.6.0",
    "webpack-cli": "^2.0.15"
  },
  "devDependencies": {
    "@types/node": "^8.0.0",
    "@types/webpack-env": "^1.13.6",
    "awesome-typescript-loader": "^5.0.0"
  }
}

Configs look fine. I don’t see any problem with them.

As you don’t have any error messages, it seems that router is not triggered at all. And this is very strange as router code is rather simple. It possible that you have some extension in chrome which alters the way how onHashChange event is processed in the browser.

Just to be sure the default router expects to have urls like

some.com/index.html#!/top/view

you need to use UrlRouter if you wish to use urls like

some.com/top/view

There is a Typescript starter for the Webix Jet - GitHub - webix-hub/jet-start at typescript.

Also, Webix Jet was updated a day ago, the previous version has one path in the code where errors were silenced, You can try the updated version, it may show some error message now.