What are our requirements for the DirList view? It renders the list of directories in the current path. When a user selects a directory from the list, it changes the current path. Subsequently, it updates the list to match the content of the new location:
./js/View/DirList.js
class DirListView {
constructor( boundingEl, dirService ){
this.el = boundingEl;
this.dir = dirService;
// Subscribe on DirService updates
dirService.on( "update", () => this.update( dirService.getDirList() ) );
}
onOpenDir( e ){
e.preventDefault();
this.dir.setDir( e.target.dataset.file );
}
update( collection ) {
this.el.innerHTML = "";
collection.forEach(( fInfo ) => {
this.el.insertAdjacentHTML( "beforeend",
`<li class="dir-list__li" data-file="${fInfo.fileName}">
<i class="icon">folder</i> ${fInfo.fileName}</li>` );
});
this.bindUi();
}
bindUi(){
const liArr = Array.from( this.el.querySelectorAll( "li[data-file]" ) );
liArr.forEach(( el ) => {
el.addEventListener( "click", e => this.onOpenDir( e ), false );
});
}
}
exports.DirListView = DirListView;
In the class constructor, we subscribe for the DirService "update" event. So, the view gets updated every time the event fired. Method update performs view update. It populates the bounding box with list items built of data received from DirService . As it is done, it calls the bindUi method to subscribe the openDir handler for click events on newly created items. As you may know, Element.querySelectorAll returns not an array, but a non-live NodeList collection. It can be iterated in a for..of loop, but I prefer the forEach array method. That is why I convert the NodeList collection into an array.
The onOpenDir handler method extracts target directory name from the data-file attribute and passes it to DirList in order to change the current path.
Now, we have new modules, so we need to initialize them in app.js:
./js/app.js
const { DirService } = require( "./js/Service/Dir" ),
{ DirListView } = require( "./js/View/DirList" ),
dirService = new DirService();
new DirListView( document.querySelector( "[data-bind=dirList]" ), dirService );
dirService.notify();
Here, we require new acting classes, create an instance of service, and pass it to the DirListView constructor together with a view bounding box element. At the end of the script, we call dirService.notify() to make all available views update for the current path.
Now, we can run the application and observe as the directory list updates as we navigate through the filesystem:
npm start