Models
View modules return the UI configuration of the components. You can put data loading logic in views, which is relevant for prototyping and considered bad practice for real-life apps.
Good practice is to separate data loading logic from UI configuration and put it in separate modules - models. A model stores all functionality related to some data entity. This division of UI and data is an advantage because if the data changes, all you have to do is change the data model. There is no need to modify all the views that use the data.
In the data model, you can define:
a DataCollection that will load the data and manage saving;
a method that will fetch the data from backend.
There are several types of models in Webix Jet:
shared models
dynamic models
remote models
services for data
models with webix.remote
1. Shared Data
For relatively small data used in many components, you can load data into Webix DataCollection. This way, you make a single request to the server, store the data on the client side and sync it with the necessary views.
Loading
You can export either the whole collection or an accessor function that will return it.
Saving
A collection will handle save operations as well. You need to provide a save URL for a collection, so that it can send all updates made from views to the server:
Data Parsing
To use the data in a component, you can parse it. You must parse data in init(), not in config() (leave config() for the UI). Have a look at the example with a datatable:
All the changes made in the datatable are saved to the server.
Models for Options of Select Boxes
You can use models to load options of select boxes, e.g.:
And for options of Datatable select editors:
Syncing Components to DataCollection
You can also sync a data component inside a Jet view with a DataCollection. Let's sync the datatable with records:
Mind that if you synced a data component to a DataCollection, you must perform add/remove operations on the master collection, while the synced view will reflect these changes automatically. Slave views can only update the master.
Shared Data Transport
To return several types of data and distribute data chunks to different views, a shared data transport can be used.
A shared data model can look like this:
The model communicates with the shared data feed and can provide different data chunks for different views, for example, specific data for a grid and common data for other components.
Each component must have its own model as well. For example, this is the data model for a grid:
A component expects that sharedData will return an array of objects or a promise of an array of objects. If you are returning data in a different format, you can add a data transformation for the promise chain:
A grid can use this model like this:
With forms, you should use a different approach:
where id
is the ID of the record from DataCollection that you want to load into the form.
Note: if you have a single record in DataCollection, you can use the DataRecord object instead:
or just a plain JS object:
2. Dynamic Data for Big Data
As browser resources are limited, big collections should not be stored on the client side. Dynamic model is for big data (less than 10K records) used only once that must not be cached.
Loading
The data can be loaded from a server directly with an AJAX request:
It can be a service, a script, a function, etc. and it should return either a data object/array or a promise that will be resolved with the needed data.
To parse data, pass the return value of getData to view.parse:
You can also load data from local storage:
Saving
To save data, you must provide a pattern for saving. Let's add one more function to the records model:
The saveData() function provided as the save property of a data widget, enables DataProcessor, which will call this function for all additions, removals and updates. Let's define a way to save data in init() of a view:
Loading and saving data can also be in config of the view module, if needed:
3. Remote Models for Huge Data
In case data is really huge, you can drop the whole concept of separating data from UI and rely on the dynamic loading of Webix components (Datatable, Dataview, List, Tree). Data will be loaded in portions when needed. For that, load data in the view configuration. You can do it with the url property. For saving data, use the save property.
Data can also be dynamically loaded with the load method:
Webix dynamic loading pattern allows loading data in portions, provided that your backend returns the response as: { data:[], total_count:1000, pos:100}. When the component is scrolled (or tree branches are opened) the component itself can send the request to the server for a new portion of data using the defined data url.
Shared vs Dynamic vs Remote models
Let's recap main differences of the three ways to load and save data:
Model | Data Size | Usage |
---|---|---|
Shared | Small | Many times |
Dynamic | Big | Once |
Remote | Huge | Handy for prototyping |
4. Services as Data Sources
You can use services instead of models as data sources. Suppose there is a list of customers and a grid that displays records on a selected customer. Here is how you can use a service that returns the ID of a selected list item:
A better and shorter way is:
5. Using Webix Remote with Webix Jet
You can use webix.remote instead of sending AJAX requests. You must have a server-side script with a class for getting the data:
The class with all its methods is used by webix.remote in a model:
webix.remote can also be used to create a DataCollection:
Models with webix.remote can be imported and parsed it into views:
webix.remote is better then an AJAX request for several reasons:
1. You don't need to serialize data after loading.
Compare the results of these two requests:
After receiving the response of the AJAX request, you have to call JSON.parse(data1)
to turn a string into an object. The response of the second request is already an object.
2. Requests with webix.remote are safer due to CSRF-security.
3. Several requests are sent as one, which makes operations faster.
Further reading
For more details on services, read:
Last updated