Angel
1.x
1.x
  • Introduction
  • Example Projects
  • Awesome Angel
  • 1.1.0 Migration Guide
  • Social
    • Angel on Gitter
    • Angel on Medium
    • Angel on YouTube
  • The Basics
    • Installation & Setup
      • Without the Boilerplate
    • Requests & Responses
    • Dependency Injection
    • Basic Routing
    • Request Lifecycle
    • Middleware
    • Controllers
    • Handling File Uploads
    • Using Plug-ins
    • Rendering Views
    • REST Client
    • Testing
    • Error Handling
    • Pattern Matching and Parameter
    • Command Line
  • Flutter
    • Writing a Chat App
    • Flutter helper widgets
  • Services
    • Service Basics
    • TypedService
    • In-Memory
    • Custom Services
    • Hooks
      • Bundled Hooks
    • Database-Agnostic Relations
    • Database Adapters
      • MongoDB
      • RethinkDB
      • JSON File-based
  • Plug-ins
    • Authentication
    • Configuration
    • Diagnostics & Logging
    • Reverse Proxy
    • Service Seeder
    • Static Files
    • Validation
    • Websockets
    • Server-sent Events
    • Toggle-able Services
  • Middleware/Finalizers
    • CORS
    • Response Compression
    • Security
    • File Upload Security
    • shelf Integration
    • User Agents
    • Pagination
    • Range, If-Range, Accept-Ranges support
  • PostgreSQL ORM
    • Model Serialization
    • Query Builder + ORM
    • Migrations
  • Deployment
    • Running in Isolates
    • Configuring SSL
    • HTTP/2 Support
    • Ubuntu and nginx
    • AppEngine
    • Production Mode
  • Front-end
    • Mustache Templates
    • Jael template engine
      • Github
      • Basics
      • Custom Elements
      • Strict Resolution
      • Directive: declare
      • Directive: for-each
      • Directive: extend
      • Directive: if
      • Directive: include
      • Directive: switch
    • compiled_mustache-based engine
    • html_builder-based engine
    • Markdown template engine
    • Using Angel with Angular
  • Advanced
    • API Documentation
    • Contribute to Angel
    • Scaling & Load Balancing
    • Standalone Router
    • Writing a Plugin
    • Task Engine
    • Hot Reloading
    • Real-time polling
Powered by GitBook
On this page
  • Defining Elements
  • Passing Data
  • Specifying a Tag Name
  • Emitting without a Tag Name
  1. Front-end
  2. Jael template engine

Custom Elements

HTML is good for its purpose, because each element (ex. div, a, ul), has its own purpose, and when invoked, reproduces specific functionality.

The goal of proposals like Web Components, and frameworks like React, Vue, and Angular, is to let developers create custom components that encapsulate data and can be called to reproduce specific output.

Jael also supports defining elements; in fact, they are analogous to defining functions in Dart code.

The benefit of defining custom elements in Jael as opposed to in a client-side framework is that they build directly to standard HTML, and require no additional features in an end-user's browser.

Defining Elements

To define your own element, simply use the <element> tag:

<element name="todo-item">
    <input type="checkbox" checked=todo.completed disabled>
    {{ todo.text }}
</element>

The best practice is to define elements in their own file, so that they can be imported into the scope using an tag:

<extend src="layout.jl">
    <block name="content">
        <include src="todo-item.jl" />
        <todo-item for-each=todos @todo=item />
    </block>
</extend>

Passing Data

You might have noticed that in the earlier example, some attributes of the todo-item were prefixed with an arroba (@), while others were not. There is, of course, a reason for this.

When rendering a custom element, attributes with the @ are injected into the custom element's scope. This is analogous to passing arguments to a function.

Attributes without the @ are passed to the root of the created element. Thus, you can pass attributes like class and style to custom elements, and therefore apply visual effects, etc.

Directives like if and for-each also work with custom elements, of course.

Specifying a Tag Name

By default, custom elements are replaced with a div. There may be times you wish to override this, for example, to render a todo-item as an a element.

Use the special as attribute to facilitate this:

<todo-item as="a" for-each=todos @todo=item />

Emitting without a Tag Name

There may be times when you need to emit the contents of an element, without a container element. In such a case, pass as=false, and the contents will be rendered in the current context, rather than in a new element.

PreviousBasicsNextStrict Resolution

Last updated 6 years ago