DEV Community

Jay Landrum
Jay Landrum

Posted on

Data binding

This second post will describe how to bind data to elements/components. In my approach I tried to simplify how the framework handles data.

In web development it's very common to need: If some array exists Then render each item in the array.

Angular separates these steps into two structural directives, *ngIf and *ngFor which can't be applied to the same element. I believe React requires the developer to return a default empty array in place of a falsy value (but this may have changed since I last worked with React).

It seemed to me "If falsy, do nothing" was worth handling instead of relying on the developer to guard the framework against falsy values. Also, non-arrays should be treated as single-element arrays. These assumptions result in a flexible data property that handles each of these inputs:

  • falsy -> []
  • truthy -> [truthy]
  • [...any] -> [...any]

Element Data Binding

// single truthy value
div({ data: () => "Hello World" }, (message: string) => 
    span({}, () => message)
)

// array of values
div({ data: () => ["Hello", "World"] }, (message: string) => 
    span({}, () => message)
)

// falsy value
div({ data: () => false }, (message) => 
    span({}, () => message)
)
Enter fullscreen mode Exit fullscreen mode

Results in:

<div> <!-- "Hello World" -->
    <span>Hello World</span>
</div>

<div> <!-- ["Hello", "World"] -->
    <span>Hello</span>
    <span>World</span>
</div>

<div> <!-- false -->
    <!-- nothing is rendered -->
</div>
Enter fullscreen mode Exit fullscreen mode

Sandbox link

Component Data Binding

Components declare an arbitrary input type using the first generic parameter of the Component<T> class. Within a Component, input data is accessed using this.Data property. When using a component, data is passed to the component using the data property of the component configuration object.

// Input type
type MessageHeaderData = { message: string };
// Type is included as part of the Component definition
class MessageHeader extends Component<MessageHeaderData> {
  Template() {
    return h1({}, () => this.Data.message);
  }
}

// Pass MessageHeaderData to the component
messageHeader({ data: () => ({ message: "Hello World" }) });
Enter fullscreen mode Exit fullscreen mode

Sandbox link

Next post will cover adding event listeners to elements/components.

Top comments (0)