Showing posts with label Web Components. Show all posts
Showing posts with label Web Components. Show all posts

Thursday, November 8, 2018

Managing Persisted State for Oracle JET Web Component Variable with Writeback Property

Starting from JET 6.0.0 Composite Components (CCA) are renamed to be Web Components (I like this new name more, it sounds more simple to me). In today post I will talk about Web Component writeback property and importance of it.

All variables (observable or not) defined inside Web Component will be reset when navigating away and navigating back to the module where Web Component is included. This means you can't store any values inside Web Component, because these values will be lost during navigation. Each time when we navigate back to module, all Web Components used inside that model will be reloaded, this means JS script for Web Component will be reloaded and variables will be re-executed loosing previous values. This behaviour is specific to Web Component only, values for variables created in the owning module will not be reset.

If you want to keep Web Component variable value, you will need to store variable state outside of Web Component. This can be achieved using Web Component property with writeback support.

Let's see how Web Component behaves on runtime. Source code is available on my GitHub repo.

Here I got basic Web Component included into dashboard module:


Web Component doesn't implement anything except JET switcher. Once switcher state is changed, variable is updated in JS script:


Variable which holds switcher state in Web Component:


Web Component is reloaded each time we navigate away and come back to the module - this means variables will be reset. This is how looks like - imagine we open module for the first time, switcher position is OFF:


Change it to be ON:


Navigate to any other module and come back - you will see that switcher is reset back to default OFF state, this means variable was reset (otherwise we should see ON state):


If you want to keep variable state, then it should be maintained outside of Web Component. To achieve this, create Web Component property to hold variable value, make sure set this property with writeback support:


For debugging purposes, add logging into Web Component, this will help to see when it will be reloaded:


Switcher variable must be initialized from Web Component property. Very first time it will be empty, but as soon as user will changed switcher state -  next time when Web Component is reloaded, it will assign correct value which was selected before:


When switcher state is changed, we need to handle this event and make sure that Web Component property is updated with new value:


Writeback property must be assigned with observable variable which is created in the module. Variable reference must be writable with {{}} brackets:


Once value will be changed inside Web Component, this change will be propagated up to observable variable defined in the module. Next time when we navigate away and come back to the module - we will pass recent value to the Web Component:


This is how it works now. Load module, change switcher state (see in the log -  Web Component was loaded once):


Navigate to any other module:


Come back to the module, where Web Component is included. See in the log - Web Component is reloaded, but switcher variable value is not lost, because it was saved to module observable variable through Web Component writeback property:

Wednesday, February 7, 2018

Oracle JET Composite Components - Manual for JET Coder

JET Composite Components - are useful not only to build UI widgets, but also to group and simplify JET code. In this post, I will show how to wrap JET table into composite component and use all essential features, such as properties, methods, events and slots.

Sample app code is available on GitHub. JET table is wrapped into composite component, it comes with slot for toolbar buttons:


What is the benefit to wrap such components as JET table into your own composite? To name a few:

1. Code encapsulation. Complex functionality, which requires multiple lines of HTML and JS code resides in the composite component
2. Maintenance and migration. It is easier to fix JET specific changes in single place
3. Faster development. There is less steps to repeat and less code to write for developer, when using shorter definition of the wrapper composite component

Sample application implements table-redsam component, for the table UI you can see above. Here is component usage example, very short and clean:


All the properties specific to given table are initialised in the module. Developer should provide REST endpoint, key values, pagination size and column structure. The rest is happening in the composite component and is hidden from the developer, who wants to implement a table:


Properties

We should take a look into array type property. Such property allows to pass array into component. This can be useful either to pass array of data to be displayed or array of metadata to help with component rendering. In our case we pass array of metadata, which helps to render table columns. Array type property is based on two attributes - Header Text and Field. Properties are defined in composite component JSON file:


Properties are retrieved from variable inside component and are assigned to local variables:


This is table implementation inside component, columns are initialised from component property:


Slots

Slot defines a placeholder, where developer who is using composite component can add additional elements. Slot is defined in component JSON definition file:


To define slot, JET slot component should be defined inside composite. You can control layout and location where slot will be rendered:


In our case, we use slot for table toolbar buttons. These buttons are added later, when developer is using composite. To place button into slot, put button inside composite component tag and assign defined slot name for the button. This will allow to render button in the slot:


Methods

Method defined in composite component, can be called from outside. In example below, I call JS function from toolbar slot button:


Function gets composite by ID and calls exposed method:


Method should be defined in composite JSON definition:


Method is implemented inside composite JS module:


Events

Events allows to implement external listeners. Basically this allows to override composite logic in external functions. Event is declared in composite JSON definition:


Composite tag contains event property mapped with external JS function, which will be called when event happens inside composite:


Function code in the module, it prints current row selection key:


Table is defined with listener property inside composite:


Listener inside composite initiates event, which will be distributed outside and handled by method defined in composite tag on-handle-selection property:


Let's see how it works. Call Method button invokes method inside composite:


Table row selection first triggers listener inside composite, then it initiates event and external listener is invoked too:


I think this lists pretty much all of the essential functionality given by JET composite components. I hope you will find it useful in your development.