Conversation
|
I've done virtualizing of contacts page. There are two solutions, the second I like more |
js-core/phoneApp/main.js
Outdated
| ]; | ||
|
|
||
| const captions = ['Name', 'Last name', 'Email']; | ||
| const footerContent = [ |
There was a problem hiding this comment.
footer content is a static no need to virtualize it
js-core/phoneApp/main.js
Outdated
| } | ||
| ] | ||
|
|
||
| const contactsPage = { |
There was a problem hiding this comment.
please use class instead of object
phoneApp/contacts.js
Outdated
| email: 'ViktorKriv@ec.ua' | ||
| } | ||
| ]; | ||
| this.footerContent = [ |
There was a problem hiding this comment.
it's just a static content, not a data that should be virtualized.
The difference between static content in "virtualized" for example,
The server would never know how many pages do you have but the server would know about users.
So you make a decision based on that knowledge
|
Footer was made like a static content |
phoneApp/common/footer.js
Outdated
| } | ||
|
|
||
| renderFooter() { | ||
| document.body.innerHTML += this.createFooter(); |
There was a problem hiding this comment.
please do not use document.body :)
create an additional tag and work inside it.
You can meet some unpredictable behavior if you rewrite the whole body content. It will be very hard to debug it and found a mistake
phoneApp/common/footer.js
Outdated
| } | ||
|
|
||
| createFooter(){ | ||
| return `<footer class="footer"> |
There was a problem hiding this comment.
you can just place such html-layout inside render
phoneApp/keypad.js
Outdated
| buttonsHandler(){ | ||
| let buttonsParent = document.querySelector('.keypad-holder'); | ||
|
|
||
| buttonsParent.addEventListener('click', this.clickHandler) |
There was a problem hiding this comment.
are you sure it works correctly?
phoneApp/index.html
Outdated
| <tr> | ||
| <td>Влад</td> | ||
| <td>Яма</td> | ||
| <td>VladYama@ec.ua</td> |
There was a problem hiding this comment.
feel free to delete commented part
phoneApp/keypad.js
Outdated
| class KeypadPage { | ||
| constructor(){ | ||
| this.title = 'Keypad'; | ||
| this.buttonsValues = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#', '']; |
There was a problem hiding this comment.
please move all content specifiec part to innerHTML it's better to omit such data inside
phoneApp/keypad.js
Outdated
| <span class = "tab-text">Contacts</span> | ||
| </a> | ||
| <a href="keypad.html" class="tab"> | ||
| <span class="glyphicon glyphicon-th" aria-hidden="true"></span> |
There was a problem hiding this comment.
this.renderLink({glyphicon:'pencil', href:'keypad.html'})
this.renderLink({glyphicon:'th', href:'contacts'})
this.renderLink({glyphicon:'pencil', href})
this.renderLink({glyphicon:'pencil', href})
phoneApp/keypad.js
Outdated
| } | ||
|
|
||
| render(){ | ||
| document.body.innerHTML = this.renderHeader() + this.renderMain() + this.renderFooter(); |
There was a problem hiding this comment.
please move all HTML specific content to render, and remove additional properties
for example:
renderHeader, renderMain, renderFooter
phoneApp/main.js
Outdated
| } | ||
| ] | ||
|
|
||
| const contactsPage = { |
There was a problem hiding this comment.
please create class ContactsPage and move all logic there
phoneApp/main.js
Outdated
| let nav = this.newEl('div', null, {className: 'main-nav'}); | ||
|
|
||
| footerContent.forEach((item) => { | ||
| let link = this.newEl('a', null, {className: `tab ${item.additionalClass}` , hrefAttr: item.href } ); |
There was a problem hiding this comment.
please create innerHTML instead of createElement
phoneApp/main.js
Outdated
| }, | ||
|
|
||
| setAttribute(element, attributes) { | ||
| let {className, typeAttr, forAttr, idAttr, placeholderAttr, hrefAttr, ariahiddenAttr} = attributes; |
|
|
||
| this.pages = { | ||
| contacts: new ContactsPage(this.state), // тут передали ссылку на this.state | ||
| adduser: new AddUser(this.state), |
There was a problem hiding this comment.
I guess there a typo with formatting
phoneApp/js/app.js
Outdated
| </footer>`; | ||
|
|
||
| //this.initializeRouterHandlers(); | ||
| this.appDOMNode = mountNode.querySelector('#app'); // сюда будем делать рендер всех страниц |
There was a problem hiding this comment.
getElementById working around in 10 times faster than querySelector, I guess it's better to switch it
phoneApp/js/app.js
Outdated
| parent.addEventListener('click', (e) => { | ||
| e.preventDefault(); | ||
| //let target = e && e.target; | ||
| let target = e && e.target && (e.target.closest('a') || e.target.classList.contains('tab')); |
There was a problem hiding this comment.
oh... such checks look like a bit overhead.
You can add additional attributes to every link and indicate "user clicked on link" that way
There was a problem hiding this comment.
on real word usage probably we should be always 100% be sure about our target
phoneApp/js/app.js
Outdated
|
|
||
| if (target.classList.contains('active')) return; | ||
| if (target.classList.contains('tab')) { | ||
| let active = document.querySelector('.active'); |
There was a problem hiding this comment.
querySelector is always performance costly operation it better to omit every time you can do it.
So, for example, you could the same solution as we did with a slider in class.
phoneApp/js/app.js
Outdated
|
|
||
| let href = target.getAttribute('href'); | ||
| //console.log(href); | ||
| this.state.activePage = href.replace(/-/g, '').toLowerCase(); |
There was a problem hiding this comment.
probably href.replace(/-/g, '').toLowerCase() such transformation adding new mental layout for understanding your app. You could just make "already" prepared data in the HTML without requires to transform it in future.
Or you can just use your HTML-attribute to indicate path of navigation and build "Map" to connect your active page
phoneApp/js/user.js
Outdated
| </div>`; | ||
| } | ||
|
|
||
| renderLink(options) { |
There was a problem hiding this comment.
I guess it's not used anymore? we may delete it
phoneApp/js/user.js
Outdated
| @@ -0,0 +1,70 @@ | |||
| class User { | |||
| constructor(globalState){ | |||
| this.state = globalState; //стал равен this.state-у со страницы App.js | |||
There was a problem hiding this comment.
something went wrong with the formatting. Try to install prettier to improve your code-base formatting.
phoneApp/js/app.js
Outdated
|
|
||
| } | ||
|
|
||
| initializeRouter () { |
There was a problem hiding this comment.
pretty sure you can create an additional file and call it "Router.js" - and move all specific to navigation logic in.
Then initialize as other pages.
The main goal what we trying to solve the minimal splitting by responsibilities have you feel it?
phoneApp/js/app.js
Outdated
| } | ||
|
|
||
| renderLink(options) { | ||
| let {href, glyphicon, text, active} = options; |
There was a problem hiding this comment.
it could be moved to Router.js also
phoneApp/js/app.js
Outdated
|
|
||
|
|
||
| switchRouter() { | ||
| const parent = document.querySelector('.main-nav'); |
There was a problem hiding this comment.
I think we can make such selector once - and remember the link to it, no need to make it on every
| let buttonsParent = document.querySelector('main'); | ||
| buttonsParent.addEventListener('click', this.clickHandler.bind(this)); | ||
| } | ||
| buttonsHandler() { |
| buttonsParent.addEventListener('click', this.clickHandler.bind(this)); | ||
| } | ||
| buttonsHandler() { | ||
| let buttonsParent = document.querySelector("main"); |
There was a problem hiding this comment.
please use const instead of let
phoneApp/js/editContact.js
Outdated
| e && | ||
| e.target && | ||
| (e.target.closest("button") || | ||
| e.target.classList.contains("add-btn")); |
There was a problem hiding this comment.
what if another dev would change that className at button - javascript would break ?
We shouldn't rely on classsNames
phoneApp/js/editContact.js
Outdated
| e.target && | ||
| (e.target.closest("button") || | ||
| e.target.classList.contains("add-btn")); | ||
| if (active == false) return; |
There was a problem hiding this comment.
if(!active) {
return
}
phoneApp/js/editContact.js
Outdated
| if (active == false) return; | ||
|
|
||
| let input = active.querySelector("input"); | ||
| input.style.backgroundColor = "lightgreen"; |
There was a problem hiding this comment.
probably you can make it something like with CSS
:focus {
}JavaScript not really required there
phoneApp/js/keypad.js
Outdated
| buttonsParent.addEventListener('click', this.clickHandler.bind(this, placeToInsertNumbers)); | ||
| window.addEventListener('keypress', this.keyHandler.bind(this, placeToInsertNumbers)); | ||
| buttonsHandler() { | ||
| let buttonsParent = document.querySelector("main"); |
There was a problem hiding this comment.
please you const keyword instead of let
| "click", | ||
| this.clickHandler.bind(this, placeToInsertNumbers) | ||
| ); | ||
| window.addEventListener( |
There was a problem hiding this comment.
are ever remove such listener?
for example when-even you changing a page
phoneApp/js/app.js
Outdated
| name: "Дарий", | ||
| lastName: "Смирнов", | ||
| email: "DariySmirnov@ec.ua" | ||
| }, |
There was a problem hiding this comment.
I guess such mock data no need anymore because you download them from the server ?
| let insertedNumbersArr = display.innerHTML.split(""); | ||
| if (insertedNumbersArr.length > 0) { | ||
| let numberWithoutLast = insertedNumbersArr.slice(0,-1).join(''); | ||
| let numberWithoutLast = insertedNumbersArr.slice(0, -1).join(""); |
There was a problem hiding this comment.
please you const instead of let
phoneApp/js/router.js
Outdated
| let target = | ||
| e && | ||
| e.target && | ||
| (e.target.closest("a") || e.target.classList.contains("tab")); //You can add additional attributes |
There was a problem hiding this comment.
I'm pretty sure you don't need such event delegation because of your event working on a small area of responsibilities.
function switchRounter, should only change the router and don't make any checks and probably has a minimal of conditionalsa
No description provided.