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
Main Application
- app.html - Contains the main application layout, instantiates the header and footer component and creates a container for the views.
- app.dart - Handles navigation events and replaces the view inside the view container (see below)
- app.css
Web Components
Header and Footer
- header.html - Web Component for header
- footer.html - Web Component for footer
Views
- contact.html - Web Component for the Contacts View
- contact.dart - Dart file containing ContactsView class
- products.html - Web Component for the Products View
- products.dart - Dart file containing ProductsView class
Switching Between Views
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…