Rasti.ViewRasti.ComponentRasti.ViewArrayRasti.ComponentRasti.SafeHTMLRasti.ComponentRasti.ComponentRasti.EmitteranythisobjectEmitternodeArray.<node>Rasti.ViewRasti.ViewnodeRasti.ViewRasti.ViewRasti.ViewRasti.ViewstringRasti.ViewComponents are a special kind of View that is designed to be easily composable,
making it simple to add child views and build complex user interfaces.
Unlike views, which are render-agnostic, components have a specific set of rendering
guidelines that allow for a more declarative development style.
Components are defined with the Component.create static method, which takes a tagged template string or a function that returns another component.
Extends: Rasti.View
See: Component.create
| Param | Type | Description |
|---|---|---|
| options | object |
Object containing options. The following keys will be merged to this: model, state, key, onDestroy, onRender, onCreate, onChange. |
Properties
| Name | Type | Description |
|---|---|---|
| key | string |
A unique key to identify the component. Used to recycle child components. |
| model | object |
A Rasti.Model or any emitter object containing data and business logic. The component will listen to change events and call onChange lifecycle method. |
| state | object |
A Rasti.Model or any emitter object containing data and business logic, to be used as internal state. The component will listen to change events and call onChange lifecycle method. |
Example
import { Component, Model } from 'rasti';
// Create Timer component.
const Timer = Component.create`
<div>
Seconds: <span>${({ model }) => model.seconds}</span>
</div>
`;
// Create model to store seconds.
const model = new Model({ seconds: 0 });
// Mount timer on body.
Timer.mount({ model }, document.body);
// Increment `model.seconds` every second.
setInterval(() => model.seconds++, 1000);
Rasti.ViewRasti.ComponentRasti.ViewArrayRasti.ComponentRasti.SafeHTMLRasti.ComponentRasti.ComponentRasti.ComponentListen to change event on a model or emitter object and call onChange lifecycle method.
The listener will be removed when the component is destroyed.
By default the component will be subscribed to this.model and this.state.
Kind: instance method of Component
Returns: Rasti.Component - The component instance.
| Param | Type | Description |
|---|---|---|
| model | Rasti.Model |
A model or emitter object to listen to changes. |
Rasti.ViewDestroy the Component.
Destroy children components if any, undelegate events, stop listening to events, call onDestroy lifecycle method.
Kind: instance method of Component
Returns: Rasti.View - Return this for chaining.
| Param | Type | Description |
|---|---|---|
| options | object |
Options object or any arguments passed to destroy method will be passed to onDestroy method. |
Lifecycle method. Called when the view is created, at the end of the constructor.
Kind: instance method of Component
| Param | Type | Description |
|---|---|---|
| options | object |
The view options. |
Lifecycle method. Called when model emits change event.
By default calls render method.
This method can be extended with custom logic.
Maybe comparing new attributes with previous ones and calling
render when needed.
Kind: instance method of Component
| Param | Type | Description |
|---|---|---|
| model | Rasti.Model |
The model that emitted the event. |
| changed | object |
Object containing keys and values that has changed. |
| […args] | any |
Any extra arguments passed to set method. |
Lifecycle method. Called after the component is rendered.
Component.RENDER_TYPE_HYDRATE as the argument.Component.RENDER_TYPE_RENDER as the argument.Component.RENDER_TYPE_RECYCLE as the argument.Kind: instance method of Component
| Param | Type | Description |
|---|---|---|
| type | string |
The render type. Possible values are: Component.RENDER_TYPE_HYDRATE, Component.RENDER_TYPE_RENDER and Component.RENDER_TYPE_RECYCLE. |
Lifecycle method. Called when the view is destroyed.
Kind: instance method of Component
| Param | Type | Description |
|---|---|---|
| options | object |
Options object or any arguments passed to destroy method. |
ArrayTagged template helper method.
Used to create a partial template.
It will return a one-dimensional array with strings and expressions.
Components will be added as children by the parent component. Template strings literals
will be marked as safe HTML to be rendered.
This method is bound to the component instance by default.
Kind: instance method of Component
Returns: Array - Array containing strings and expressions.
| Param | Type | Description |
|---|---|---|
| strings | TemplateStringsArray |
Template strings. |
| …expressions | any |
Template expressions. |
Example
import { Component } from 'rasti';
// Create a Title component.
const Title = Component.create`
<h1>${self => self.renderChildren()}</h1>
`;
// Create Main component.
const Main = Component.create`
<main>
${self => self.renderHeader()}
</main>
`.extend({
// Render header method.
// Use `partial` to render an HTML template adding children components.
renderHeader() {
return this.partial`
<header>
<${Title}>${({ model }) => model.title}</${Title}>
</header>
`;
}
});
Rasti.ComponentRender the Component.
this.el is not present, the Component will be rendered as a string inside a DocumentFragment and hydrated, making this.el available. The onRender lifecycle method will be called with Component.RENDER_TYPE_HYDRATE as an argument. this.el is present, the method will update the attributes and inner HTML of the element, or recreate its child component in the case of a container. The onRender lifecycle method will be called with Component.RENDER_TYPE_RENDER as an argument. Component will call the onRender lifecycle method with Component.RENDER_TYPE_RECYCLE as an argument. Kind: instance method of Component
Returns: Rasti.Component - The component instance.
Rasti.SafeHTMLMark a string as safe HTML to be rendered.
Normally you don't need to use this method, as Rasti will automatically mark string literals
as safe HTML when the component is created and when
using the Component.partial method.
Be sure that the string is safe to be rendered, as it will be inserted into the DOM without any sanitization.
Kind: static method of Component
Returns: Rasti.SafeHTML - A safe HTML object.
| Param | Type |
|---|---|
| value | string |
Helper method used to extend a Component, creating a subclass.
Kind: static method of Component
| Param | Type | Description |
|---|---|---|
| object | object |
Object containing methods to be added to the new Component subclass. Also can be a function that receives the parent prototype and returns an object. |
Rasti.ComponentMount the component into the dom.
It instantiate the Component view using options,
appends its element into the DOM (if el is provided).
And returns the view instance.
Kind: static method of Component
| Param | Type | Description |
|---|---|---|
| options | object |
The view options. |
| el | node |
Dom element to append the view element. |
| hydrate | boolean |
If true, the view will hydrate existing DOM. |
Rasti.ComponentTakes a tagged template string or a function that returns another component, and returns a new Component class.
const Button = Component.create`<button class="button">Click me</button>`;
null, undefined, false, or an empty string, the interpolation won't render any content. const Button = Component.create`
<button class="${({ options }) => options.className}">
${({ options }) => options.renderChildren()}
</button>
`;
onEventName=${{'selector' : listener }}. They will be transformed to an event object and delegated to the root element. See View.delegateEvents. attribute="${() => true}". false attributes won't be rendered. true attributes will be rendered without a value. const Input = Component.create`
<input type="text" disabled=${({ options }) => options.disabled} />
`;
// Create a button component.
const Button = Component.create`
<button class="button">
${({ options }) => options.renderChildren()}
</button>
`;
// Create a navigation component. Add buttons as children. Iterate over items.
const Navigation = Component.create`
<nav>
${({ options }) => options.items.map(
item => Button.mount({ renderChildren: () => item.label })
)}
</nav>
`;
// Create a header component. Add navigation as a child.
const Header = Component.create`
<header>
${({ options }) => Navigation.mount({ items : options.items})}
</header>
`;
// Create a button component.
const Button = Component.create`
<button class="button">
${({ options }) => options.renderChildren()}
</button>
`;
// Create a navigation component. Add buttons as children. Iterate over items.
const Navigation = Component.create`
<nav>
${({ options, partial }) => options.items.map(
item => partial`<${Button}>${item.label}</${Button}>`
)}
</nav>
`;
// Create a header component. Add navigation as a child.
const Header = Component.create`
<header>
<${Navigation} items="${({ options }) => options.items}" />
</header>
`;
this.el will be a reference to that child component's element. // Create a button component.
const Button = Component.create`
<button class="${({ options }) => options.className}">
${self => self.renderChildren()}
</button>
`;
// Create a container that renders a Button component.
const ButtonOk = Component.create`
<${Button} className="ok">Ok</${Button}>
`;
// Create a container that renders a Button component, using a function.
const ButtonCancel = Component.create(() => Button.mount({
className: 'cancel',
renderChildren: () => 'Cancel'
}));
Kind: static method of Component
Returns: Rasti.Component - The newly created component class.
| Param | Type | Description |
|---|---|---|
| strings | string | function |
HTML template for the component or a function that mounts a sub component. |
| …expressions | * |
The expressions to be interpolated within the template. |
Emitter is a class that provides an easy way to implement the observer pattern
in your applications.
It can be extended to create new classes that have the ability to emit and bind custom named events.
Emitter is used by Model and View classes, which inherit from it to implement
event-driven functionality.
Example
import { Emitter } from 'rasti';
// Custom cart
class ShoppingCart extends Emitter {
constructor() {
super();
this.items = [];
}
addItem(item) {
this.items.push(item);
// Emit a custom event called `itemAdded`.
// Pass the added item as an argument to the event listener.
this.emit('itemAdded', item);
}
}
// Create an instance of ShoppingCart and Logger
const cart = new ShoppingCart();
// Listen to the `itemAdded` event and log the added item using the logger.
cart.on('itemAdded', (item) => {
console.log(`Item added to cart: ${item.name} - Price: $${item.price}`);
});
// Simulate adding items to the cart
const item1 = { name : 'Smartphone', price : 1000 };
const item2 = { name : 'Headphones', price : 150 };
cart.addItem(item1); // Output: "Item added to cart: Smartphone - Price: $1000"
cart.addItem(item2); // Output: "Item added to cart: Headphones - Price: $150"
Adds event listener.
Kind: instance method of Emitter
| Param | Type | Description |
|---|---|---|
| type | string |
Type of the event (e.g. change). |
| listener | function |
Callback function to be called when the event is emitted. |
Example
// Re render when model changes.
this.model.on('change', this.render.bind(this));
Adds event listener that executes once.
Kind: instance method of Emitter
| Param | Type | Description |
|---|---|---|
| type | string |
Type of the event (e.g. change). |
| listener | function |
Callback function to be called when the event is emitted. |
Example
// Log a message once when model changes.
this.model.once('change', () => console.log('This will happen once'));
Removes event listeners.
Kind: instance method of Emitter
| Param | Type | Description |
|---|---|---|
| [type] | string |
Type of the event (e.g. change). If is not provided, it removes all listeners. |
| [listener] | function |
Callback function to be called when the event is emitted. If listener is not provided, it removes all listeners for specified type. |
Example
// Stop listening to changes.
this.model.off('change');
Emits event of specified type. Listeners will receive specified arguments.
Kind: instance method of Emitter
| Param | Type | Description |
|---|---|---|
| type | string |
Type of the event (e.g. change). |
| […args] | any |
Arguments to be passed to listener. |
Example
// Emit validation error event.
this.emit('invalid');
Rasti.EmitterA Model manages an internal table of data attributes and triggers change events when any of its data is modified.
Models may handle syncing data with a persistence layer. To design your models, create atomic, reusable objects
that contain all the necessary functions for manipulating their specific data.
Models should be easily passed throughout your app and used anywhere the corresponding data is needed.
Rasti models store their attributes in this.attributes, which is extended from this.defaults and the
constructor attributes parameter. For every attribute, a getter is generated to retrieve the model property
from this.attributes, and a setter is created to set the model property in this.attributes and emit change
and change:attribute events.
Extends: Rasti.Emitter
| Param | Type | Description |
|---|---|---|
| attributes | object |
Object containing model attributes to extend this.attributes. Getters and setters are generated for this.attributes, in order to emit change events. |
Properties
| Name | Type | Description |
|---|---|---|
| defaults | object | function |
Object containing default attributes for the model. It will extend this.attributes. If a function is passed, it will be called to get the defaults. It will be bound to the model instance. |
| previous | object |
Object containing previous attributes when a change occurs. |
Example
import { Model } from 'rasti';
// Product model
class ProductModel extends Model {
preinitialize() {
// The Product model has `name` and `price` default attributes.
// `defaults` will extend `this.attributes`.
// Getters and setters are generated for `this.attributes`,
// in order to emit `change` events.
this.defaults = {
name: '',
price: 0
};
}
setDiscount(discountPercentage) {
// Apply a discount to the price property.
// This will call a setter that will update `price` in `this.attributes`,
// and emit `change` and `change:price` events.
const discount = this.price * (discountPercentage / 100);
this.price -= discount;
}
}
// Create a product instance with a name and price.
const product = new ProductModel({ name: 'Smartphone', price: 1000 });
// Listen to the `change:price` event.
product.on('change:price', () => console.log('New Price:', product.price));
// Apply a 10% discount to the product.
product.setDiscount(10); // Output: "New Price: 900"
Rasti.EmitteranythisobjectIf you define a preinitialize method, it will be invoked when the Model is first created, before any instantiation logic is run for the Model.
Kind: instance method of Model
| Param | Type | Description |
|---|---|---|
| attributes | object |
Object containing model attributes to extend this.attributes. |
Generate getter/setter for the given key. In order to emit change events.
This method is called internally by the constructor
for this.attributes.
Kind: instance method of Model
| Param | Type | Description |
|---|---|---|
| key | string |
Attribute key. |
anyGet an attribute from this.attributes.
This method is called internally by generated getters.
Kind: instance method of Model
Returns: any - The attribute value.
| Param | Type | Description |
|---|---|---|
| key | string |
Attribute key. |
thisSet an attribute into this.attributes.
Emit change and change:attribute if a value changes.
Could be called in two forms, this.set('key', value) and
this.set({ key : value }).
This method is called internally by generated setters.
The change event listener will receive the model instance, an object containing the changed attributes, and the rest of the arguments passed to set method.
The change:attribute event listener will receive the model instance, the new attribute value, and the rest of the arguments passed to set method.
Kind: instance method of Model
Returns: this - This model.
Emits: event:change, change:attribute
| Param | Type | Description |
|---|---|---|
| key | string |
Attribute key or object containing keys/values. |
| [value] | Attribute value. |
objectReturn object representation of the model to be used for JSON serialization.
By default returns a copy of this.attributes.
Kind: instance method of Model
Returns: object - Object representation of the model to be used for JSON serialization.
EmitterA View is an atomic unit of the user interface that can render data from a specific model or multiple models.
However, views can also be independent and have no associated data.
Models must be unaware of views. Views, on the other hand, may render model data and listen to the change events
emitted by the models to re-render themselves based on changes.
Each View has a root element, this.el, which is used for event delegation.
All element lookups are scoped to this element, and any rendering or DOM manipulations should be done inside it.
If this.el is not present, an element will be created using this.tag (defaulting to div) and this.attributes.
Extends: Emitter
| Param | Type | Description |
|---|---|---|
| options | object |
Object containing options. The following keys will be merged into the view instance: el, tag, attributes, events, model, template, onDestroy. |
Properties
| Name | Type | Description |
|---|---|---|
| el | node | function |
Every view has a root DOM element stored at this.el. If not present, it will be created. If this.el is a function, it will be called to get the element at this.ensureElement, bound to the view instance. See View.ensureElement. |
| tag | string | function |
If this.el is not present, an element will be created using this.tag and this.attributes. Default is div. If it is a function, it will be called to get the tag, bound to the view instance. See View.ensureElement. |
| attributes | object | function |
If this.el is not present, an element will be created using this.tag and this.attributes. If it is a function, it will be called to get the attributes object, bound to the view instance. See View.ensureElement. |
| events | object | function |
Object in the format {'event selector' : 'listener'}. It will be used to bind delegated event listeners to the root element. If it is a function, it will be called to get the events object, bound to the view instance. See View.delegateEvents. |
| model | object |
A model or any object containing data and business logic. |
| template | function |
A function that returns a string with the view's inner HTML. See View.render. |
| uid | number |
Unique identifier for the view instance. This can be used to generate unique IDs for elements within the view. It is automatically generated and should not be set manually. |
Example
import { View } from 'rasti';
class Timer extends View {
constructor(options) {
super(options);
// Create model to store internal state. Set `seconds` attribute to 0.
this.model = new Model({ seconds : 0 });
// Listen to changes in model `seconds` attribute and re-render.
this.model.on('change:seconds', this.render.bind(this));
// Increment model `seconds` attribute every 1000 milliseconds.
this.interval = setInterval(() => this.model.seconds++, 1000);
}
template(model) {
return `Seconds: <span>${model.seconds}</span>`;
}
}
// Render view and append view's element into the body.
document.body.appendChild(new Timer().render().el);
EmitternodeArray.<node>Rasti.ViewRasti.ViewnodeRasti.ViewRasti.ViewRasti.ViewRasti.ViewstringIf you define a preinitialize method, it will be invoked when the view is first created, before any instantiation logic is run.
Kind: instance method of View
| Param | Type | Description |
|---|---|---|
| attrs | object |
Object containing model attributes to extend this.attributes. |
nodeReturns the first element that matches the selector,
scoped to DOM elements within the current view's root element (this.el).
Kind: instance method of View
Returns: node - Element matching selector within the view's root element (this.el).
| Param | Type | Description |
|---|---|---|
| selector | string |
CSS selector. |
Array.<node>Returns a list of elements that match the selector,
scoped to DOM elements within the current view's root element (this.el).
Kind: instance method of View
Returns: Array.<node> - List of elements matching selector within the view's root element (this.el).
| Param | Type | Description |
|---|---|---|
| selector | string |
CSS selector. |
Rasti.ViewDestroy the view.
Destroy children views if any, undelegate events, stop listening to events, call onDestroy lifecycle method.
Kind: instance method of View
Returns: Rasti.View - Return this for chaining.
| Param | Type | Description |
|---|---|---|
| options | object |
Options object or any arguments passed to destroy method will be passed to onDestroy method. |
onDestroy lifecycle method is called after the view is destroyed.
Override with your code. Useful to stop listening to model's events.
Kind: instance method of View
| Param | Type | Description |
|---|---|---|
| options | object |
Options object or any arguments passed to destroy method. |
Rasti.ViewAdd a view as a child.
Children views are stored at this.children, and destroyed when the parent is destroyed.
Returns the child for chaining.
Kind: instance method of View
| Param | Type |
|---|---|
| child | Rasti.View |
Call destroy method on children views.
Kind: instance method of View
Ensure that the view has a root element at this.el.
You shouldn't call this method directly. It's called from the constructor.
You may override it if you want to use a different logic or to
postpone element creation.
Kind: instance method of View
nodeCreate an element.
Called from the constructor if this.el is undefined, to ensure
the view has a root element.
Kind: instance method of View
Returns: node - The created element.
| Param | Type | Default | Description |
|---|---|---|---|
| tag | string |
"div" |
Tag for the element. Default to div |
| attributes | object |
Attributes for the element. |
Rasti.ViewRemove this.el from the DOM.
Kind: instance method of View
Returns: Rasti.View - Return this for chaining.
Rasti.ViewProvide declarative listeners for DOM events within a view. If an events object is not provided,
it defaults to using this.events. If this.events is a function, it will be called to get the events object.
The events object should follow the format {'event selector': 'listener'}:
event: The type of event (e.g., 'click').selector: A CSS selector to match the event target. If omitted, the event is bound to the root element.listener: A function or a string representing a method name on the view. The method will be called with this bound to the view instance.By default, delegateEvents is called within the View's constructor. If you have a simple events object,
all of your DOM events will be connected automatically, and you will not need to call this function manually.
All attached listeners are bound to the view, ensuring that this refers to the view object when the listeners are invoked.
When delegateEvents is called again, possibly with a different events object, all previous listeners are removed and delegated afresh.
The listeners will be invoked with the event and the view as arguments.
Kind: instance method of View
Returns: Rasti.View - Returns this for chaining.
| Param | Type | Description |
|---|---|---|
| [events] | object |
Object in the format {'event selector' : 'listener'}. Used to bind delegated event listeners to the root element. |
Example
// Using a function.
class Modal extends View {
events() {
return {
'click button.ok': 'onClickOkButton',
'click button.cancel': function() {}
};
}
}
// Using an object.
Modal.prototype.events = {
'click button.ok' : 'onClickOkButton',
'click button.cancel' : function() {}
};
Rasti.ViewRemoves all of the view's delegated events.
Useful if you want to disable or remove a view from the DOM temporarily.
Called automatically when the view is destroyed and when delegateEvents is called again.
Kind: instance method of View
Returns: Rasti.View - Return this for chaining.
Rasti.ViewRenders the view.
This method should be overridden with custom logic.
The only convention is to manipulate the DOM within the scope of this.el,
and to return this for chaining.
If you add any child views, you should call this.destroyChildren before re-rendering.
The default implementation updates this.el's innerHTML with the result
of calling this.template, passing this.model as the argument.
⚠ Security Notice: The default implementation utilizes innerHTML, which may introduce Cross-Site Scripting (XSS) risks.
Ensure that any user-generated content is properly sanitized before inserting it into the DOM.
You can use the View.sanitize static method to escape HTML entities in a string.
For best practices on secure data handling, refer to the
OWASP's XSS Prevention Cheat Sheet.
Kind: instance method of View
Returns: Rasti.View - Returns this for chaining.
stringEscape HTML entities in a string. Use this method to sanitize user-generated content before inserting it into the DOM. Override this method to provide a custom escape function. This method is inherited by Component and used to escape template interpolations.
Kind: static method of View
Returns: string - Escaped string.
| Param | Type | Description |
|---|---|---|
| str | string |
String to escape. |