Implementation of delayed loading technology for HTML5 tree components of HT for Web, hthtml5
The HTML5 tree component of HT for Web has the delayed loading function, which is useful for those who need to read hierarchical dependency data from the server, when you need to obtain data, you can initiate a request to the server. This reduces the load on the server and the waiting time of the browser, making page loading smoother and enhancing the user experience.
The Demo used for demonstration today is that the client requests the server to read the system file directory structure and displays the system file directory structure through the HTML5 tree component of HT for Web.
First, let's design the server. The Demo server uses Node. js, using Node. js express, socket. io, fs, and http modules, Node. I will not elaborate on js-related knowledge here. There are a bunch of online teaching materials. socket is recommended here. for more information about io, see http://socket.io/get-started/chat /.
Server code:
var fs = require('fs'), express = require('express'), app = express(), server = require('http').createServer(app), io = require('socket.io')(server), root = ‘/Users/admin/Projects/ht-for-web/guide‘;io.on('connection', function(socket){ socket.on('explore', function(url){ socket.emit('file', walk(url || root)); });});app.use(express.static('/Users/admin/Projects/ht-for-web'));server.listen(5000, function(){ console.log('server is listening at port 5000');});
Io listens to the connection event and obtains a socket. socket then listens to a custom event called javase. After obtaining data through the url parameter, it distributes a custom event called file, for the client to listen and handle it accordingly; through the app. use in combination with express. set the project path in static mode. Finally, let the server listen to port 5000.
At this point, a simple server has been built, and now you can access the server through http: // localhost: 5000. Wait, it seems that something is missing. By the way, the method for getting the directory structure of the system file is missing. OK. Let's take a look at how the code for getting the entire site file is written:
function walk(pa) { var dirList = fs.readdirSync(pa), key = pa.substring(pa.lastIndexOf('/') + 1), obj = { name: key, path: pa, children: [], files: [] }; dirList.forEach(function(item) { var stats = fs.statSync(pa + '/' + item); if (stats.isDirectory()) { obj.children.push(walk(pa + '/' + item)); } else { obj.files.push({name: item, dir: pa + '/' + item}); } }); return obj;}
As you can see, using recursive methods to traverse sub-directories layer by layer, the code is nothing advanced, and I believe everyone can understand it. Let's take a look at the running effect:
Duang ~ The file directory structure has come out. Isn't it cool? It's a huge amount of code. As a matter of fact, there are not many codes. You can refer to them as follows:
<!DOCTYPE html>
This is all the HTML code, plus a total of 50 lines of blank lines, how do you feel like HT for Web is very powerful. Let's take a look at what these codes have done:
- Socket. io needs to introduce <script src = "/socket. io/socket. io. js "> </script>, actually does not exist in my project/socket. io/socket. io. js files, but they can be used normally. I will not talk about the specific reasons. Let's study them by yourself;
- The most important thing is to introduce the core package of HT for Web <script src = "/lib/core/ht. js "> </script>, if this package is not introduced, the following HT for Web component will not be available;
- The code is followed. First, create a data container DataModel to store the node data of the file directory, create a TreeView object, and reference the newly created data container. Then, listen to the file event through the socket, obtain the data returned by the server. In the callback function, call the createChildren and createFiles functions to create a file directory node object and add it to the data container. Finally, initiate a data request to the server, that is to say, the EMR event is distributed through socket.
The overall idea is like this. Of course, there is still a gap between the delayed loading technology of the tree components we want to implement. So, how does the delayed loading technology of the HTML5 tree component of HT for Web be implemented? Don't worry. start exploring now.
First, we need to transform the way to get the file directory to walk, because in the method described above, we use to load the entire site file directory, therefore, we need to transform the walk method to get only the first-level directory structure. It is very easy to transform the recursive part to get the current node. The specific code is as follows:
Obj. children. push (walk (pa + '/' + item); // change the above Code to the following code obj. children. push ({name: item, path: pa + '/' + item });
In this way, the server only requests the first-level file directory structure in the current request path. Next, we need to adjust the client code. First, we need to set the loader for the tree:
tree.setLoader({ load: function(data) { socket.emit('explore', data.a('path')); data.a('loaded', true); }, isLoaded: function(data) { return data.a('loaded'); }});
Loader contains two methods: load and isLoaded. The functions of these two methods are to load data and determine whether the data has been loaded. In the load method, the javase event is distributed to the socket, the path of the current node is a parameter that requests data from the server. Then, the loaded attribute of the current node is set to true. In the isLoaded method, the loaded attribute of the current node is returned. If the returned value is true, tree will not request data from the server by executing the load method.
Next, we need to remove the two callback methods of createChildren and set the loaded attribute of the created node to true in the createFiles method so that no expanded icon exists before the node is not a directory. The code after the createChildren and createFiles methods are modified is as follows:
function createChildren(children, parent, dm) { children.forEach(function(child) { var n = createData(child, parent); dm.add(n); });}function createFiles(files, parent, dm){ files.forEach(function(file){ var n = createData(file, parent); n.a('loaded', true); dm.add(n); });}
In this way, the HTML5 tree component delayed loading technology of HT for Web is designed. I printed the Request Path on the server console to see if the delayed loading is true, for example:
See, the console prints four records. The first one is printed during the request and directory. I expanded the three directories in the browser and printed the corresponding directory path on the console.
Now, this directory looks annoying. It only has text. Apart from the expanded icon in front of the seat, it can be used to differentiate Files And Directories. There is no other difference, so I decided to make some changes to it, let every level-1 Directory have icons, and different files correspond to different icons. Let's take a look at the results:
How about it? Can we see at a glance what the file is? This is a style issue, and I will not elaborate on it one by one, just go to the Code:
<!DOCTYPE html>
At the end, complete server code is attached:
var fs = require('fs'), express = require('express'), app = express(), server = require('http').createServer(app), io = require('socket.io')(server), root = '/Users/admin/Projects/ht-for-web/guide';io.on('connection', function(socket){ socket.on('explore', function(url){ socket.emit('file', walk(url || root)); });});app.use(express.static('/Users/admin/Projects/ht-for-web'));server.listen(5000, function(){ console.log('server is listening at port 5000');});function walk(pa) { var dirList = fs.readdirSync(pa), key = pa.substring(pa.lastIndexOf('/') + 1), obj = { name: key, path: pa, children: [], files: [] }; dirList.forEach(function(item) { var stats = fs.statSync(pa + '/' + item); if (stats.isDirectory()) { obj.children.push({name: item, path: pa + '/' + item}); } else { obj.files.push({name: item, dir: pa + '/' + item}); } }); return obj;}