Durandal Framework
repository·master·Indexed 23 days ago
https://github.com/bluespire/durandalA cross-device, cross-platform JavaScript client framework for building Single Page Applications (SPAs) for PC, Mac, Linux, iOS, and Android. Durandal utilizes a composition-based model to bind View Models to Views, leveraging core dependencies including RequireJS, Knockout, jQuery, and Bootstrap. It provides a consistent API for SPA development using Promises for asynchronous operations and a router for managing navigation state.
What's inside Durandal
- Durandal is a lightweight JavaScript framework designed for building Single Page Applications (SPAs). It leverages existing libraries like jQuery, Knockout, and RequireJS to provide a familiar development experience without reinventing core web technologies. It is designed to be platform-agnostic, supporting web deployment, mobile deployment (via PhoneGap), and desktop deployment (via AppJS).
Overview of Durandal
masterDurandal is a JavaScript-based client framework designed for building cross-device and cross-platform Single Page Applications (SPAs). It is intended to simplify the creation and maintenance of applications targeting PC, Mac, Linux, iOS, and Android.
Note: This project is no longer active and has been superseded by Aurelia.
Project Structure in the Durandal Starter Kit
masterWhen working with the Durandal Starter Kit, the project is organized into the following directories and files:
- App/: Contains the main application code, organized into AMD modules and HTML views.
- App/main.js: The entry point for application startup.
- Content/: Contains CSS, fonts, and images.
- Scripts/: Contains third-party script libraries.
- App_Start/DurandalBundleConfig.cs: Configuration for CSS and script library bundling.
- Durandal/Index: The host page containing the base HTML, links, and script references.
What is an Overridable Designation in Durandal
masterIn the Durandal documentation, certain functions are marked with the[overridable]indicator. This designation signals that the function is a deliberate extension point designed to be replaced by your own implementation to customize framework behavior. Replacing an overridable function is a supported way to extend Durandal and is intended to be safe from negative side-effects.What is composition in Durandal
masterDurandal uses two types of composition to build applications:
- Object Composition: Achieved via AMD/RequireJS. Modules can depend on other modules (e.g., Module B requires Module A), allowing for modularization of logic.
- Visual Composition: Achieved via the
composebinding. This allows developers to break views into reusable components and connect them to their corresponding viewmodels (modules). This is the central mechanism for rendering the UI, including widgets and modal dialogs.
Understand Module Ids
masterEvery module has a unique Id derived from its path relative to the application'sbaseUrl. While Durandal assigns this Id to a semi-private field__moduleId__, you should not access that field directly. Instead, use the system module'sgetModuleId(object)function to inspect a module's Id.How views and modules work together in Durandal
masterDurandal uses a module-view pattern where modules (JavaScript files) provide the logic and data, and views (HTML files) provide the structure.
Key principles:
- Pairing: Modules and views are paired together by convention (e.g.,
customerList.jspairs withcustomerList.html). This pairing is managed by the view locator. - Data Binding: Use Knockout.js bindings within the HTML view to synchronize the DOM with the module's properties. When a property in the module changes, the DOM updates automatically, and user interactions in the DOM can update the module.
- Root Element: Every view must have exactly one root element. If multiple root elements are present, Durandal will wrap them in a
<div>. If comments are found at the root, they will be removed.
- Pairing: Modules and views are paired together by convention (e.g.,
Use the compose binding for navigation
masterThe
composebinding is a powerful Knockout-based feature used to swap views dynamically. In a shell/layout, you can bind thecomposeinstruction to an observable (like a router's active item). When the observable changes, Durandal:- Detects the change.
- Uses the
viewLocatorto find the appropriate view for the new module. - Data-binds the new view and model together.
- Inserts the result into the DOM at the binding location.
- Applies an optional transition animation.
Syntax:
<!--ko compose: { model: activeItemObservable, afterCompose: callback, transition: 'animationName' }--><!--/ko--><!--ko compose: { model: router.activeItem, afterCompose: router.afterCompose, transition:'entrance' }--><!--/ko-->Use Knockout binding handlers to encapsulate view logic
masterThe most common way to interact with the DOM in Durandal is by creating custom Knockout (KO) binding handlers. This allows you to encapsulate view-related code (like wrapping jQuery plugins) and keep your modules free of direct DOM manipulation. Durandal's own composition and widget bindings are implemented as custom KO binding handlers.Manage navigation and screen state lifecycle
masterDurandal's router and lifecycle management handle complex navigation scenarios:
Routing
The router supports:
- Mappings: Route-to-module mappings or convention-based routing.
- Navigation Modes: Support for both
hashandpushStatenavigation. - Data-Driven Routes: Support for parameters, optional parameters, splats, and query strings.
- Child Routers: Ability to encapsulate entire areas of an application with their own routing structures.
Screen Activation Lifecycle
To handle 'dirty' states (e.g., preventing a user from navigating away from an unsaved form), Durandal implements a screen activation lifecycle. This allows any screen, fragment, or component to synchronously or asynchronously control the flow into and out of a navigation event. This lifecycle is also used to manage the behavior of modal dialogs.
Handle asynchronous operations with Promises
masterDurandal is designed around Promises to handle asynchronous data requests and resource loading.
- API Consistency: All potentially asynchronous Durandal APIs return promises.
- Promise Libraries: While jQuery provides the default promise implementation, you can switch this out for other libraries like Q.
- Observable Module: When targeting ES5 browsers, enabling the
observablemodule allows the Knockout binding system to data-bind directly to promises. For example, you can use aforeachbinding directly on a promise that resolves to an array of data, removing the need to manually resolve the promise in your application logic.
Use composition lifecycle callbacks for view manipulation
masterFor high-performance view manipulation or scenarios where you need to bypass standard databinding, Durandal provides several lifecycle hooks on your objects. These hooks allow you to intercept the view at different stages of its creation and attachment.