Few weeks ago I had to write a JavaScript program that builds a "Wizard Form" from a JSON data, where a step needs data of the preceding step. Since I was using a vanilla JavaScript I had to implement data binding from scratch. I wanted to share with you that the way I achieved databinding in my project.
Let me start by explain why I need databinding in the project.
We have a step where a user needs to import a CSV file , the imported CSVthe scenario in which a data binding is important. file is parsed and stored in data store. The succeeding step needs to make a tabular data from the CSV file.
The JSON used to build both steps looks the following, note: I have stripped out some lines for clarity.
[
step1 : {
type: "csv",
output: "studentList"
},
step2 {
type: "table",
input: "studentList"
}
]
I the config file We have 2 steps, each step has a type
attribute, a type
attributive tells the form builder the kind of the step it should build.
csv
step type lets user to import CSV files, while table
step type builds a tabular data
We can summarize the above config file as following.
The first step lets the user import a CSV file, while the second step builds a tabular data from the imported CSV file.
In order to achieve my task goal, I need a data binding between the table builder and the CSV file importer. So I have implemented it as the following.
I created a central data store from which all data are stored and the changes to the store are dispatched to each subscribers of particular store element subscribers.
The CVS file importer imports the CSV file, parses and , stores in the central data store as studentList
. The central data store stores/updates studentList
and dispatches a data changed event to the subscribers of studentList
.
The Store Code
/**
* A centrall store object.
*/
let store = {
changeSubscribers: {
},
/**
* Update/Create a new store item
* */
addData(name, data) {
// Update/Create
this[name] = data;
// Inform subscribers of this field that it is updated.
if (this.changeSubscribers[name] !== undefined) {
this.changeSubscribers[name].forEach(subscriberCallBack => {
subscriberCallBack(new Event("changed"));
});
}
},
/**
* Register subscribers
*/
addChangeListener(name, callback) {
if (this.changeSubscribers[name] === undefined) {
this.changeSubscribers[name] = [];
}
let id = this.changeSubscribers[name].push(callback);
return id;
}
}
Updating the store
/**
* Update the files store
*/
store.addData( input.name,input.files[0]
Subscribing to the data change
store.addChangeListener( "studentList", event=>{
// Logic goes here
})
Top comments (0)