export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true, data:[
{ id:1, title:"The Godfather", ... }
]};
}
});BAD
import {data} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true };
}
init(view){
view.parse(data);
}
});GOOD
//models/records
export const data = new webix.DataCollection({
data:[
{ id:1, title:"The Godfather", ... }
]
});
//or
export function getData(){ return data; };
import {data} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true };
}
init(){
view.parse(data);
//or view.sync(data);
}
}); //models/records
export const data = new webix.DataCollection({
url:"/some/records",
save:"rest->/some/records"
});
import {data} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true };
}
init(){
view.sync(data);
}
}); //models/records
export function getData(){
return webix.ajax("/some/records");
}; import {getData} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true }
}
init(){
view.parse(getData());
}
}); //models/records
export function getData(){
return webix.ajax("/some/records");
};
export function saveData(id, operation, data){
if(operation =="update") //"add", "delete"
return webix.ajax().put("/some/records", data);
...
};
import {getData, saveData} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true, save:saveData };
}
init(){
view.parse(getData());
}
}
export default class DataView extends JetView {
config(){
return {
view:"datatable",
autoConfig:true,
url:"/some/records",
save:"rest->/some/records"
};
}
});Dynamic loading
Server filtering and sorting
Relatively small
Used many times
Shared Data
Relatively big
Used once
Dynamic Data
AND
OR
Huge data
Prototyping
Remote Models
OR
Be pragmatic!
Async data: Promises
Webix Promise Interface
var promise = webix.promise.defer();
promise.then(() => {
console.log(message);
}).fail(() => {
console.log(err);
});
promise.resolve("Success!"); let promise = new Promise((resolve, reject) => {
//smth async
setTimeout(() => {
resolve("Success!");
}, 250);
});
promise.then((message) => {
console.log(message);
}).catch((err) => {
console.log(err);
});JS Promises
Async data: Promises
Webix Ajax Interface
//load by method
let promise = datatable.load(url);
promise.then(() => {}).fail(() => {});
//load by property
{ view:"datatable", id:"dt", url:url }
$$("dt").waitData.then(() => {}).fail(() => {}); let promise1 = webix.ajax(url, params); //load
let promise2 = webix.ajax().post(url, params); //save
promise1.then((data) => {}).fail((err) => {});
promise2.then((data) => {}).fail((err) => {});Ajax -related promises in widgets
Wait for loading:
Async data: Use at once
import {data} from "models/records";
import {options} from "models/options";
export default class DataView extends JetView {
config(){
return {
cols:[
{ view:"datatable", id:"table", columns:[
{ id:"title", fillspace:true},
{ id:"categoryId", collection:options}
]}
]
};
}
init(view){
this.$$("table").sync(data);
}
}
[
{ id:1, title:"...", categoryId:1 },
{ id:2, title:"...", categoryId:2 },
{ id:3, title:"...", categoryId:3 }
][
{ id:1, value:"Crime"},
{ id:2, value:"Thriller"},
{ id:3, value:"Drama" }
]Data
Options
Async data: Wait until loaded
view/collection.waitData
import {data} from "models/records";
export default class DataView extends JetView {
config(){
return { view:"datatable", autoConfig:true };
}
init(view){
view.sync(data);
data.waitData.then(() => {
view.select(view.getFirstId());
});
}
}Events
init(view){
data.attachEvent("onAfterLoad", () => {
view.select(view.getFirstId());
});
}Async data: Wait for all
webix.promise.all
import {data} from "models/records";
import {options} from "models/options";
export class DetailsView extends from JetView {
config(){
return { template:"#title#. #category#"};
}
urlChange(view, url){
webix.promise.all([
data.waitData,
options.waitData
]).then(()=>{
let id = url[0].params.id;
let item = webix.copy(data.getItem(id));
item.category = options.getItem(item.categoryId).value;
view.parse(item);
});
}
} export default class ChartView extends JetView {
config(){
let chart = {
view:"chart", type:"bar",
series:[]
};
return webix.ajax("data/colors").then(function(data){
const colors = data.json();
for(let i in colors){
chart.series.push({
value:"#"+i+"#", color:colors[i]
});
}
return {
rows:[ chart, { template:"Chart description"}]
};
});
}
init(view){
view.queryView({view:"chart"}).load(url);
}
}Async data: Saving
view/collection.waitSave (Webix 6.3+)
//models/records
export const data = new webix.DataCollection({
url:"load/records",
save:"save/records"
});
// views/data
webix.dp(data).attachEvent("onAfterSync", (status, text, data) => {
//webix.message("Data was saved");
});Dataprocessor events
// view
data.waitSave(() => {
data.add({ });
}).then((res) => {
view.select(res.id);
});a single operation
multiple operations
Not Covered Topics
Links
Demo: click here
Task for practice: click here
Follow-up text: click here