I'm trying to integrate an Angular 12 app into a ZK application.
Here is my index.zhtml:
<?xml version="1.0"?>
<!DOCTYPE html>
<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:z="zul" xmlns="native" lang="fr">
<head>
<meta charset="utf-8">
<title>ZK + Angular 12</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<z:div
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm')@init('com.c4_soft.zk_angular_demo.MyViewModel')"
validationMessages="@id('vmsgs')">
...
<z:button label="ZK ++" onClick="@command('cmd')"></z:button>
</z:div>
<app-root></app-root>
</body>
</html>
My problem (actually, the first one, I anticipate quite a few others):
attributes in "zul" namespace are case sensitive (z:div viewModel
and z:button onClick
for instance) but ng build
transforms it to lower-case.
How to prevent ng build from processing attributes case for xml tags in namespaces it doesn't know about?
Since I am from the ZK side I don't actually know whether there is a compiler flag/switch do disable the automatic lower casing.
I think angular is trying to compile too much here. zhtml/zul-files are ZK specific formats and need to be parsed/executed by ZK's DHtmlLayoutServlet at server side at runtime. If you process these files with ng build
it looks like this compiler is unaware of ZK's syntax and changes/breaks things according to it's own conventions defaults (internally angular uses the parse5 html parser which deliberately switches all tag/attribute names to lowercase)
Bottom line: you can't compile zhtml/zul files with ng build
.
Instead what can do is to compile your angular application into JS and then include it into the zhtml page using a script tag.
<?xml version="1.0"?>
<!DOCTYPE html>
<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:z="zul" xmlns="native" lang="fr">
<head>
<meta charset="utf-8">
<title>ZK + Angular 12</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script src="yourlibs.js"></script>
<script src="morelibs.js"></script>
<script>/*script initializing app-root*/</script>
</head>
<body>
<z:div
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm')@init('com.c4_soft.zk_angular_demo.MyViewModel')"
validationMessages="@id('vmsgs')">
...
<z:button label="ZK ++" onClick="@command('cmd')"></z:button>
</z:div>
<app-root></app-root>
</body>
</html>
Here a few links to existing integration examples based on angular 2 and 8:
In both cases the JS files are added explicitly to the zhtml/zul files independent of the actual build process.
https://github.com/zkoss-demo/zkangular2/blob/master/src/main/webapp/hero/index.zhtml
The above is for ZK being the main application and allows adding nested angular components/pages.
If you want your angular app to be the main app then you might look into zk-embedded, which provides a JS api to integrate zul pages into arbitrary html pages ()