I am going to build complex application having many different views. Imagine for example eshop solution. There can be a lot of different views:
Now I am little bit confused, how to build such a complex application using Web UI. I would like to have the HTML templates for the views separated in multiple files and having some logic to determine, which one should be rendered.
Assume I want to have a single master template containing basic things like header and footer, then I have a lot of content templates, these should get injected into the right place inside the master template.
Until now, I have always seen only small single-template examples of using Dart Web UI, so I have no idea, how to achieve this.
I've put together a little example of how I currently do it (hope we will soon see a larger best practice example application for this):
For the complete source code of this example see gist: How to build a Web UI application with multiple views in Dart
The standard way to instantiate Web Components is by using <x-foo></x-foo>
in HTML.
As we have different views, we will have to instantiate the Web Components inside our Dart code. Doing this we have to manually call the Web Components lifecycle methods. This is not straight forward and might be improved in the future (see Issue 93 which also contains some exmples).
Here is how you can switch views (source of app.dart
):
import 'dart:html';
import 'package:web_ui/web_ui.dart';
import 'contact.dart';
import 'products.dart';
void main() {
// Add view navigation event handlers
query('#show-contact-button').onClick.listen(showContactView);
query('#show-products-button').onClick.listen(showProductView);
}
// Used to call lifecycle methods on the current view
ComponentItem lifecycleCaller;
/// Switches to contacts view
void showContactView(Event e) {
removeCurrentView();
ContactView contactView = new ContactView()
..host = new Element.html('<contact-view></contact-view>');
lifecycleCaller = new ComponentItem(contactView)..create();
query('#view-container').children.add(contactView.host);
lifecycleCaller.insert();
}
/// Switches to products view
void showProductView(Event e) {
removeCurrentView();
ProductsView productsView = new ProductsView()
..host = new Element.html('<products-view></products-view>');
lifecycleCaller = new ComponentItem(productsView);
lifecycleCaller.create();
query('#view-container').children.add(productsView.host);
lifecycleCaller.insert();
}
void removeCurrentView() {
query('#view-container').children.clear();
if (lifecycleCaller != null) {
// Call the lifecycle method in case the component needs to do some clean up
lifecycleCaller.remove();
}
}
And here is the source for app.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>A Complex Web UI Application</title>
<link rel="stylesheet" href="app.css">
<!-- import the header and footer components -->
<link rel="components" href="header.html">
<link rel="components" href="footer.html">
<!-- import the view components -->
<link rel="components" href="contact.html">
<link rel="components" href="products.html">
</head>
<body>
<header-component></header-component>
<div id="view-container"></div>
<button id="show-contact-button">show contact view</button>
<button id="show-products-button">show products view</button>
<footer-component></footer-component>
<script type="application/dart" src="app.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
Note: I had to import the view components via <link rel="components" href="contact.html">
even though I do not directly reference it in the HTML file.