UNPKG

neft

Version:

Universal Platform

206 lines (147 loc) 5.12 kB
# 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> ```