Resolved
Written on
·
214
2
안녕하세요 김정환 강사님!
`꿀`보이스이셔서 귀 호강하며 잘 듣고있습니다.
강의를 1년전에 들었다면 수많은 시행착오를 안겪지 않았까 싶을 정도로 너무나 알찬 강의 감사드립니다.
다름이 아니라,
강의에는 없지만, 실습 과제 진행중에 잘 하고 있는건지, 확인을 받아보고 싶은 마음에 질문을 하게 되었습니다.
약간의 고도화? 를 거쳐 확장성을 부여하기 위해 고심끝에 아래와 같이 작성해 보았습니다.
대략적인 설명과 소스 코드의 일부분입니다.
이외는 강의 대용과 동일 합니다
const detail = { type: null, key: null, content: null }}
this.on('submit', e => e.preventDefault())
this.inputEl.addEventListener('keyup', (e) => {
detail.type = 'key'
detail.key = e.key
this.onKeyUp(e, detail)
})
this.resetEl.addEventListener('click', (e) => {
detail.type = 'button'
this.onClickReset(e, detail)
})
this.showResetBtn(this.inputEl.value.length)}
const isValidText = this.inputEl.value.length;
if (!isValidText && event.key !== KEY_ENTER) {
this.onClickReset(event, detail)
return
}
detail.content = this.inputEl.value.trim()
switch (event.key) {
case KEY_ENTER:
isValidText && this.onSubmit(event,detail)
break
case KEY_ESC:
this.onClickReset(event,detail)
break
}
this.showResetBtn(false)}
this.inputEl.value = ''
this.inputEl.focus()
detail.content = ''
this.emit(EVENT_RESET, detail)
this.emit(EVENT_SUBMIT, detail)}
export default {
...
...
onSubmit(event) {
const { type, key, content } = event.detail
console.log(tag, `onSubmit() type=${ type } key=${ key }`, content)
},
onResetForm(event) {
const { type, key, content } = event.detail
console.log(tag, `onReset() type=${ type } key=${ key }`, content)
},
}
이런 식으로 FormView 외부에서 작동할 것을 대비해서
이벤트 디테일 객체를 외부로 전달하는 것이 맞는것인지, 혹은 더나은 방식과,
고쳐야 될 부분 에 대한 , 김정환 강사님의 조언을 구하고자 질문하게 되었습니다.
읽어주셔서 감사합니다!
Answer 2
1
FormView를 사용하는 MainController에서 좀더 세밀한 제어를 하기위한 의도인것 같네요. Truestar님 아이디어처럼 이벤와 함께 상세정보(detail)를 전달하는 아이디어도 좋은것 같습니다. 두 가지 첨언드릴게요.
1. 단일 detail 객체를 사용해서 각 이벤트 핸들러에서 수정하고 있는 부분이 조금 우려됩니다. keyup 이벤트 핸들러에서는 type과 key를 모두 설정하는 반면 click 핸들러에서는 type만 설정하기 때문에 잘못된 key 가 들어갈 여지가 있어 보여요. 리터럴 객체를 전달하거나 원시 타입을 여러개 전달하는 방식은 어떨까요?
2. FormView 가 이벤트 정보를 전달하는 것은 외부에서 사용하라는 의도 같은데요. MainController에서 이걸 사용하는 경우가 있을까요? 오히려 상세한 이벤트 동작은 FormView 내부에서 처리해서 감추는 것이 어떨까요?
0
"각 세부 이벤트 핸들러에서 상세정보를 받는것은 좋은 아이디어" 라고 해주셔서 너무 보람찹니다^^
첨언 해주신 부분을 아래와 같이 적용해보았습니다.
아래는 질문은 아니구요, 결과물 정도로 생각해주시면 좋을것 같습니다^^
(질문한 시점 이후로 많은부분을 생각하며 리팩토링을 시도해 보았습니다)
this.inputEl.addEventListener('keyup', (e) => this.onKeyUp(e, e.key, 'key'))선언:
this.resetEl.addEventListener('click', (e) => this.onResetForm(e, null, 'button'))
FormView.onKeyUp = function(event, key, from = 'key') {
...
FormView.onReset = function(event, key, from) {
...
FormView.onSubmit = function(event, key, from) {
...
const tag = '[FormView]'컴포넌트간 결합도를 낮추는 방안으로 작성해 보았습니다.
...
...
FormView.onSubmit = function(event, key, from) {
this.emit(FormEvent.SUBMIT, {...})
}
import View, { ViewEvent } from './View.js'
/* fields */
const
tag = '[FormView]',
FormView = Object.create(View),//> OLOO 생성패턴 - https://jeonghwan-kim.github.io/2018/05/12/extended-component.html
State = {
reset: true,
isWriting: false,
keyword: null,//>향후 LocalStorage 값 가져오기
submitKeyword: null,//>향후 LocalStorage 값 가져오기
}
export const
Key = {
ENTER: 'Enter',
ESC: 'Escape',
}
/* methods */
FormView.setup = function(el) {
console.log(tag, 'setup()', el)
this.resetEl = el.querySelector('[type=reset]')
this.inputEl = el.querySelector('[type=text]')
this.inputEl.value = ''//> 향후 LocalStorage 에서 로딩
return this
.init(el)
.updateState()
.bindEvent()
.showResetBtn(false)
}
FormView.updateState = function() {
State.keyword = this.resetEl.value.trim()
State.submitKeyword = State.keyword
return this
};
FormView.bindEvent = function() {
this.on('submit', e => e.preventDefault())
this.inputEl.addEventListener('input', (e) => this.onInputForStateSync(e))//> https://developer.mozilla.org/en-US/docs/Web/API/InputEvent
this.inputEl.addEventListener('keyup', (e) => this.onKeyUp(e, e.key, 'key'))
this.resetEl.addEventListener('click', (e) => this.onReset(e, null, 'button'))
return this
}
FormView.showResetBtn = function(show = false) {
this.resetEl.style.display = show ? 'block' : 'none'
return this
}
/* handler methods */
// `반응성`개념 적용을 위한 키 입력값으로 상태값 설정
FormView.onInputForStateSync = function(event) {
State.keyword = this.inputEl.value.trim()
State.isWriting = !! State.keyword.length
this.showResetBtn(State.isWriting)
}
FormView.onKeyUp = function(event, key, from = 'key') {
const isResetBefore = ! State.reset
if (! State.isWriting && key !== Key.ENTER) {
return isResetBefore && this.onReset(event, key, from)
}
switch (event.key) {
case Key.ENTER:
State.isWriting && this.onSubmit(event, key, from)
return
case Key.ESC:
isResetBefore && this.onReset(event, key, from)
return
}
State.reset = false
}
// Reset 조건 - reset 이 이미 되어잇는경우 다시 리셋하지 않음.
FormView.onReset = function(event, key, from) {
console.log(tag, 'onResetForm()')
this.showResetBtn(false)
this.inputEl.value = ''
this.inputEl.focus()
State.keyword = ''
State.reset = true
! State.reset && this.emit(ViewEvent.RESET, { key, from })
}
// 전송조건 - 빈 문자 이거나, 동일 키워드가 아닌경우 전송됨
FormView.onSubmit = function(event, key, from) {
const isEmpty = ! State.keyword.length;
const isSameKeywordBefore = State.keyword === State.submitKeyword;
if (isEmpty || isSameKeywordBefore) return
console.log(tag, 'onSubmit() keyword:', State.keyword)
this.updateState()
this.emit(ViewEvent.SUBMIT, {
key,
from,
keyword: State.keyword,
})
}
export default FormView
강사님의 조언으로 많은 도움이 되었습니다
혹시 뭔가 떠오르는 것이 있으시다면, `옛다 이거 하나더 먹어라`는 마음으로
던저주신다면 감사히 경청하겠습니다.
읽어주셔서 감사합니다!
무척 열심히 공부하시는 것 같네요. 이런식으로 고민하시면서 구조를 개선해 나가는 건 좋다고 생각합니다. 실무에서도 '딱 이것이 최선이다'라는것은 찾기 어려운 것 같고요. 자주 코드를 들여다보고 변화에 따라 개선해 나가는 것이 방법이라고 생각합니다.