Knockout에서 만드는 카운트 다운 타이머 (컴퓨팅의 훌륭함)
16597 단어 knockoutjsMVVM자바스크립트
스크린샷
디자인
도메인 모델을 공유하는 애플리케이션이 없기 때문에 모델에는 제약이 없습니다.
모델에 제약이 없기 때문에 반드시 모델과 뷰 모델을 분리할 필요는 없습니다.
여기에서는 공부를 위해 MVVM에 따라 모델과 뷰 모델을 나눕니다.
모델
타이머
도메인 모델을 공유하는 애플리케이션이 없기 때문에 모델에는 제약이 없습니다.
모델에 제약이 없기 때문에 반드시 모델과 뷰 모델을 분리할 필요는 없습니다.
여기에서는 공부를 위해 MVVM에 따라 모델과 뷰 모델을 나눕니다.
모델
타이머
를 잡습니다.
뷰 모델
크게 세 가지 작업이 있습니다.
표시용 속성
開始
또는 中止
) 표시 상태 및 갱신 처리
이벤트 핸들러
보기
을 표시합니다.
구현
모델
남은 시간과 감산 처리를 구현합니다.
보통 JavaScript의 객체입니다.
남은 시간은 밀리초 단위로 관리합니다.
초기값은 10초로 했습니다.
model = {
restTime: 10000,
decrement(ms) {
this.restTime -= ms
}
}
뷰 모델
표시용 속성
남은 시간
observable 을 사용하여 변경 사항을 모니터링할 수 있습니다.
this.restTime = ko.observable(model.restTime)
남은 시간 라벨
모델의 남은 시간은 밀리초 단위이지만 화면에 초 단위로 표시됩니다.
computed 을 사용하여 this.restTime
의 값을 초 단위로 변환하는 observable
를 만듭니다.
this.restTimeLabel = ko.computed(() => this.restTime() / 1000)
버튼 라벨
computed을 사용하여 내부 상태 (bool 값)를 표시 용으로 변환하는 observable
를 만듭니다.
this.toggleSwitchLabel = ko.computed(() => this._isStop() ? '開始' : '中止')
_isStop
는 상태 판정용의 내부 함수입니다.
_isStop() {
return this.state() === STATE_STOP
}
computed
는 함수 호출의 대상인 observable
도 찾을 수 있습니다.
타이머의 시작 종료 상태
this.toggleSwitchLabel
에서 참조하는 observable
입니다.
this.state = ko.observable(STATE_STOP)
이벤트 핸들러
카운트다운 ON/OFF 전환
toggle() {
if (this._isStop()) {
this.state(STATE_RUN)
} else {
this.state(STATE_STOP)
}
}
this.state
또한 observable입니다. 이 상태 변경을 감시해, 카운트 처리의 개시·종료를 제어합니다.
타이머 카운트 처리
subscribe
메서드를 사용하여 this.state
의 상태 변경을 모니터링합니다.
정지 상태가 되었을 때, window.clearInterval 로 카운트다운을 정지합니다.
시작 상태가 되었을 때, window.setInterval (을)를 사용해 1초 마다 다음의 처리를 합니다.
model = {
restTime: 10000,
decrement(ms) {
this.restTime -= ms
}
}
this.restTime = ko.observable(model.restTime)
this.restTimeLabel = ko.computed(() => this.restTime() / 1000)
this.toggleSwitchLabel = ko.computed(() => this._isStop() ? '開始' : '中止')
_isStop() {
return this.state() === STATE_STOP
}
this.state = ko.observable(STATE_STOP)
toggle() {
if (this._isStop()) {
this.state(STATE_RUN)
} else {
this.state(STATE_STOP)
}
}
this.restTime
에 모델 값을 반영 let intervalID = null
this.state.subscribe(() => {
if (this._isStop()) {
if (intervalID) {
window.clearInterval(intervalID)
intervalID = null
}
} else {
intervalID = window.setInterval(() => {
this.model.decrement()
this.restTime(this.model.restTime)
}, 1000)
}
})
이 타이머는 자동으로 멈추지 않습니다.
보기
남은 시간과 시작 버튼을 표시합니다.
<span data-bind="text: restTimeLabel">100</span>秒
<button data-bind="text: toggleSwitchLabel, click: toggle">開始</button>
소스 코드 전문
CountDown.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js"></script>
<body>
<span data-bind="text: restTimeLabel">100</span>秒
<button data-bind="text: toggleSwitchLabel, click: toggle">開始</button>
<script>
const STATE_STOP = false,
STATE_RUN = true,
model = {
restTime: 10000,
decrement(ms) {
this.restTime -= ms
}
}
class TimerViewModel {
constructor(model) {
this.model = model
this.restTime = ko.observable(model.restTime)
this.state = ko.observable(STATE_STOP)
let intervalID = null
this.state.subscribe(() => {
if (this._isStop()) {
if (intervalID) {
window.clearInterval(intervalID)
intervalID = null
}
} else {
intervalID = window.setInterval(() => {
this.model.decrement(1000)
this.restTime(this.model.restTime)
}, 1000)
}
})
this.restTimeLabel = ko.computed(() => this.restTime() / 1000)
this.toggleSwitchLabel = ko.computed(() => this._isStop() ? '開始' : '中止')
}
toggle() {
if (this._isStop()) {
this.state(STATE_RUN)
} else {
this.state(STATE_STOP)
}
}
_isStop() {
return this.state() === STATE_STOP
}
}
//main
ko.applyBindings(new TimerViewModel(model))
</script>
</body>
감상
computed가 기분 좋다.
ReactiveProperty 과 사용감이 비슷합니다.
관련 기사
INotifyPropertyChanged 구현의 불가능한 번거로움과 ReactiveProperty의 놀라운 훌륭함
Reference
이 문제에 관하여(Knockout에서 만드는 카운트 다운 타이머 (컴퓨팅의 훌륭함)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ledsun/items/bd4163c6cd1fecde4eb1
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
INotifyPropertyChanged 구현의 불가능한 번거로움과 ReactiveProperty의 놀라운 훌륭함
Reference
이 문제에 관하여(Knockout에서 만드는 카운트 다운 타이머 (컴퓨팅의 훌륭함)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ledsun/items/bd4163c6cd1fecde4eb1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)