Custom triggers on two way bindings in ef.js make syncing child properties with parent super easy
Tags: javascript, html, webdev, showdev
Published: 2021-02-19 13:52:36

First let's see a demo:

{% codepen https://codepen.io/ClassicOldSong/pen/XWNMdEq %}

You may not be familiar with the EFML syntax, goto the [official website](https://ef.js.org)(which is a little bit of outdated, but should still be fine) for a quick look and [README](https://github.com/TheNeuronProject/ef.js/blob/master/README.md) for detailed usage.

Just writing a static template with no scripting at all could link all these things together, amazing! How could ef.js do that?

Simple, with **custom two way binding trigger** which was introduced in ef.js v0.13.0.

## What is ef.js?

>ef.js was designed with simplicity and future facing in mind, with
1. completely no logic in templates;
1. no virtual dom to slow your webpage down;
1. no need for special compiler to make your project move;
1. no need for any dynamically generated functions to run which is very friendly for CSP;
1. write in pure javascript and no need for special developing environment;
1. browser supports back to IE9.

>Enjoy coding with ef.js!

I started developing ef.js 4 years ago, since Vue started using virtual dom. I'm not a huge fan of virtual dom and there's not much frameworks to choose from, so I made my own, which is another story to tell. 

Interestingly enough, my own creation beats React and Vue greatly in performance and still yet provides a very simple usage and small bundle size.

![Performance comparison with other popular frameworks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmuie8b54sjsxcstdblo.jpeg)


## Two way binding in ef.js

We are already familiar with how two way binding happens in Vue. Unfortunately, according to the [Vue doc](https://vuejs.org/v2/guide/components-custom-events.html), we still could neither have custom events being processed properly using Vue, nor a custom trigger for syncing data between parent component with children back and forth, which is a very nice feature to have in custom components.

### Events handling

While in ef.js, events are handled pretty straight forward, just `addEventListener` to the exact DOM element with what event type you wrote on the template on the exact DOM object or component delegator which is also a common DOM object. So here comes the convenience: you could actually use whatever event you want to trigger an event handler or sync any property from children to parent. For example:

```efml
>button
  @click = handleClick
```

{% codepen https://codepen.io/ClassicOldSong/pen/qBqjebW %}

which will call `$methods.handleClick` method on the component when `click` event triggered. What about a custom component emitting a custom event?

```efml
>MyCustomComponent
  @mycustomevent = {{handleCustomEvent}}
```

{% codepen https://codepen.io/ClassicOldSong/pen/qBqjeaB %}

So easy isn't it?

### Property setting

Now we know how to handle events in ef.js. So how do we handle property change? Still simple:

```efml
>input
  %value = {{inputValue}}
```

{% codepen https://codepen.io/ClassicOldSong/pen/RwogXBg %}

when we change `$data.inputValue` on the component instance, the value shown in the `input` element changes as well.

### Two way binding

Cool. When will we talk about two way binding?

We already have:

```efml
>input
  %value = {{inputValue}}
.You typed "{{inputValue}}".
```

```efml
>input
  #type = checkbox
  %checked = {{checked = true}}
.Is this checkbox checked? {{checked}}
```

{% codepen https://codepen.io/ClassicOldSong/pen/OJbgKav %}

When you type in the input box or check the checkbox, values are automatically synced to the other parts of the component with the same variable name. ef.js listens to `input`, `change` and `keyup` on elements with `value` or `checked` properties present on the element in the template.

### Custom two way binding trigger

Till now we still look very alike Vue. What's the difference? Here comes the big part: you can actually define your custom two way binding trigger!

```efml
>audio
  %currentTime@timeupdate = {{trackCurrentTime}}
.Current time of the track: {{trackCurrentTime}}
```

(Check the beginning of this article for demo)

In this demo, we defined `timeupdate` event as the trigger for updating `trackCurrentTime` from `currentTime` property of the `audio` element. We will get an automatically update each time `timeupdate` triggers! That simple!

This gives us the ability to use custom events as triggers for two way binding, without the need to mess with `input`, `change` or `keyup` events like what Vue did. We can also emit different events on the children indicating different value changes awaiting parents to sync with. Imagine what you'll need to do in Vue or React in order to get a property from a custom child component.

This feature is currently impossible in other popular frameworks like React and Vue, or you have to implement it manually using more javascript.

## Summary

ef.js is a very extensible frontend framework, which was shown in the demos with super simple usage. It's simpleness will help you think more straight in frontend development, and will help you write more performant and organized code.

This is my first post on ef.js. Very few people know this framework, so thanks for your patience to learn and read to the end. I'll make more share like this if you like it, and huge thanks to everyone who supports me in the past years of development of ef.js!

Follow me on Twitter [@ClassicOldSong](https://twitter.com/ClassicOldSong) for more updates on ef.js!