# Scripting

Each view file and [component](/views.html#component) can be scripted.

The whole *JavaScript* code put inside the `<script />` tag.

In the view file:

```xhtml
<script></script>
```

or in a [component](/views.html#component):

```xhtml
<component name="Avatar">
    <script></script>
</component>
```

## View lifecycle

Inside the `<sript />` tag you can connect to five [signals](/data-binding.html#signal):
 - `this.onCreate()`,
 - `this.onBeforeRender()`,
 - `this.onRender()`,
 - `this.onBeforeRevert()`,
 - `this.onRevert()`.

View once created is reusing. Because of that, `onCreate` signal is called only when there is no free views to use and a new one has to be created.

When a view needs to be put into a document, it's **rendered** (`onBeforeRender`, `onRender`).

When a view is no longer needed, it's **reverted** (`onBeforeRevert`, `onRevert`).

Reverted views can be rendered later.

## Custom methods

Custom methods should be created inside the `onCreate` [signal](/data-binding.html#signal) as lambda functions.

It ensures, that you have always the proper context (`this`) inside all methods.

View context can be used in [String Interpolation](/views.html#string-interpolation).

```xhtml
<script>
this.onCreate(function () {
    this.plusOne = (number) => {
        return number + 1;
    };
});
</script>
<p>${this.plusOne(2)}</p> <!-- <p>3</p> -->
```

## `this.state`

`this.state` is a [Dict](/data-binding.html#dict).
Use it to store custom data for a rendered view.

It's save to use. Automatically cleared when view is *reverted*.

Data can be read in [String Interpolation](/views.html#string-interpolation) under the `${state}` object.

Default `state` must be defined in `onRender` signal.

```xhtml
<script>
this.onCreate(function () {
    this.increment = () => {
        this.state.set('counterValue', this.state.counterValue + 1);
    };
});
this.onRender(function () {
    this.state.set('counterValue', 1);
    this.increment();
});
</script>
<p>Counter: ${state.counterValue}</p> <!-- <p>Counter: 2</p> -->
```

## `this.refs`

All nodes with [`ref`](/views.html#ref) tags are available under the `this.refs` object.

```xhtml
<script>
this.onRender(function () {
    this.refs.image.props.set('src', "rsc:background");
});
</script>
<img ref="image" /> <!-- <img src="rsc:background" /> -->
```

If node with `ref` tag renders a [component](/views.html#component), it refers to the `this` context and not no the [Virtual DOM](/views/virtual-dom.html) element.

```xhtml
<component name="Issue">
    <script>
    this.onCreate(function () {
        this.getTitle = () => 'More gifs!';
    });
    </script>
</component>

<component name="IssueList">
    <script>
    this.onRender(function () {
        console.log(this.refs.firstIssue.getTitle());
        // More gifs!
    });
    </script>
    <Issue ref="firstIssue" />
</component>

<IssueList />
```

This object is available in [String Interpolation](/views.html#string-interpolation) as `${refs}`.

## `this.node`

It refers to the main view or component [element](/views/virtual-dom.html).

More about it you'll learn in the [next chapter](/views/virtual-dom.html) but you can use it to e.g. find an element by a selector.

```xhtml
<script>
this.onRender(function () {
    const spans = this.node.queryAll('p > span');
    console.log(spans);
    // [<span>first</span>, <span>third</span>]
});
</script>
<p><span>first</span> second <span>third</span></p>
```

## `this.props`

`this.props` object contains properties used to create a [component](/views.html#component).

You should not change it.

Use it to configure creating components.

This object is available in [String Interpolation](/views.html#string-interpolation) as `${props}`.

```xhtml
<component name="User">
    <script>
    this.onCreate(function () {
        console.log(this.props.nick);
        // testslover32
    });
    </script>

    <h1>${props.nick}</h1>
</component>

<User nick="testslover32" />
```

`this.props` is an instance of [Dict](/data-binding.html#dict) and can be changed in runtime. Connect to [`this.props.onChange()`](/api/dict.html#onchange) signal if you want to detect it manually.

## `this.context`

This property refers to a [route](/routing.html) used to render this view.

You can use to make, for instance, a *HTTP* request.

```xhtml
<script>
this.onRender(function () {
    this.context.app.networking.get('/users', (err, resp) => {});
});
</script>
```

... or to get a [route.data](/api/app-route.html#data).

More about it you'll learn in [Routing](/routing.html) chapter.

This object is available in [String Interpolation](/views.html#string-interpolation) as `${context}`.

## Script file

You can move your *JavaScript* code to separated file.

`<script />` accepts `src` attribute. Use is with relative path.

```xhtml
<script src="./scriptFile.js" />
```

## CoffeeScript support

If you like to use *CoffeeScript*, you can do it by specifying the `filename` attribute with the *.coffee* extension.

```html
<script filename="view.coffee">
@onCreate ->
    @sum = (a, b) => a + b
</script>
```
