Templates & Data Context An overview of how data is used in components package Guide

Templates & Data Context

Rendering HTML

Your components HTML structure is defined by template and a data context to generate your component’s html.

Comparing to React - Instead of using a render() function to return jsx each component’s template provides the high level logic for explaining how html should be rendered from data for your component and will automatically re-render sections of a template depending on the reactivity of the data.

Templates

Your template defines how your component’s html is rendered:

  • Conditionals - Branching structures like if else if and else
  • Looping structures - Structures to iterate through data like arrays or objects
  • Reactive data - State stored with your component that should update the page when it updates
  • Function calls - Methods on your component that allow you to access content and perform tasks
  • Subtemplates - Reusable pieces of html organized as a separate file
  • Snippets - Reusable pieces of html included elsewhere in a template
  • Slots - Locations where content can be placed inside your component
  • Snippets - reusable html structures inside a component

For more information on all the features of templates check our dedicated subsection on templates.

Data Context

The templates data context is a combination of several data sources that are looked up in sequence.

For instance our template might include something like

Greetings, {name}

This will check for name in each of these locations and then return the first available defined value.

  • Global Helpers - A global helper registered across templates called name
  • Component Instance - A value or function on your component called name
  • Settings - A value name passed in via html attribute or property
  • State - An internal reactive state called name
  • Subtemplate Data - Data passed in from a parent template called name

Simplified Data Structures - A template’s data context is flat to make templates easier to read and to give flexibility when moving values between locations. For instance you may initially have a value as a property on your component, then move it to state to make it reactive, then finally move it to settings to make it user overridable without having to modify the underlying template.

Global Helpers

Global helpers are special utilities that are available across all templates and provide utilities like classMap, formatDate, concat stringify that can be used to format values for output.

For a list of global helpers please visit the dedicated global helper page in templating.

Helper Example

In this example formatDate is used to format the display of a date set in the components state.

{formatDate currentTime 'h:mm:ss a'}

For a complete list of available global helpers see global helpers.

Settings

Defining Settings

Settings are values which you want users of your component to be able to modify. To specify settings for a component simply pass in a settings object when defining a component.

Data Types - A settings type will be inferred from its default value. This means you do not need to formally declare them as String or Date.

const settings = {
name: 'Jack'
};
defineComponent({
tagName: 'name-card',
settings
});

Overriding Defaults

Settings specified for a component are defaults which can be overridden by anyone using your component by passing in different data through the DOM.

HTML Attributes

<name-card name="Sally"></name-card>

DOM Properties

const el = document.querySelector('name-card');
el.name = 'Sam';

Functions

Functions cannot be serialized so they must be passed in via Javascript. This can be handled using Query’s settings method after DOM Ready or initialize method at any point in page load.

You can also manually set the function on the corresponding DOM element.

State

State is a reactive data store that uses Signals to recompute references to a value when its underlying vaalue is modified.

Declaring State

State is designed you to store internal reactive values that can be used to re-render portions of a template when a value changes, or to rerun reactive computations when underlying reactive data changes.

const state = {
name: 'Jack'
};
defineComponent({
tagName: 'name-card',
state
});

Using State

Each component will have its own copy of state initialized with its default value set based off your configuration.

Inside a Component

You can use state inside a component by destructuring state from any lifecycle events.

component.js
const createComponent = ({self, state}) => ({
getGreeting() {
// state is { name: ReactiveVar('Jack') }
return `Hello ${state.name.value}`
}
});

Using In Templates

state like other reactive values can be accessed by name directly in templates without having to use value or get

component.html
Hello {name}

Component Instance

Defining Functionality

Your component instance stores methods and properties that implement the functionality of your component. These can be various locations where you might want to access functionality, like from other parts of the component, templates, or externally via the DOM.

Accessing in Templates

Templates can access your component directly from its data context.

Counter is {{getCounter}}

Accessing Internally

You can access your template instance as self, component, or tpl from other callbacks to invoke functionality.

For more information see lifecycle events.

const onRendered = ({ self }) => {
self.incrementCounter();
};

Accessing Externally

You can also access your component instance directly from the DOM from the component property.

For more information see from DOM.

const { component } = document.querySelector('ui-counter');
component.incrementCounter();

Subtemplates

SUI components can either be rendered to a tagname as a web component or exported to be used as subtemplates in other components. This is dependent on whether tagName is specified

When no tag name is specified they are returned as Subtemplates which can be passed in to other components.

When components are rendered as subtemplates, their data context is defined explicitly from the parent template.

For example, you might want to have a table that uses a subtemplate to output a table row, definining the data context as the row’s data for each initialization.

Data Types

You can pass any type of javascript primitive as a setting however there may be serialization requirements depending on the date type.

Strings, Numbers

Strings and numbers can be passed in either through html attributes or directly as properties.

Arrays, Objects, Dates

Arrays, objects and dates can be passed in either through attributes or properties.

When passed in as attributes the data must be passed through JSON.stringify to serialize the value as a string.

If you are passing it in as a property you can specify the value without serialization.

Order of Data Lookups

For a complete picture of how an expression is looked up from inside your template’s data context, please refer to the following chart:

Component Lifecycle