class Board extends React.Component { renderSquare(i) { return <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} />; } render() { return ( <div> <div className="board-row"> {this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)} </div> <div className="board-row"> {this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)} </div> <div className="board-row"> {this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)} </div> </div> ); } } class Game extends React.Component { constructor() { super(); this.state = { history: [{ squares: Array(9).fill(null), }], xIsNext: true, stepNumber: 0, }; } handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ history: history.concat([{ squares: squares }]), stepNumber: history.length, xIsNext: !this.state.xIsNext, }); } jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) ? false : true, }); } render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); let status; if (winner) { status = 'Winner: ' + winner; } else { status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); } const moves = history.map((step, move) => { const desc = move ? 'move #' + move : 'Game start'; return ( <li key={move}> <a href="#" onClick={() => this.jumpTo(move)}>{desc}</a> </li> ); }); return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={(i) => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } } // ======================================== ReactDOM.render( <Game />, document.getElementById('container') ); function Square(props) { return ( <button className="square" onClick={() => props.onClick()}> {props.value} </button> ); } function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; }
Dev. Chun
2016년 11월 21일 월요일
'Tic Tac Toe' Completed Code
2016년 10월 19일 수요일
Mybatis settings - mapUnderscoreToCamelCase
settings
mapUnderscoreToCamelCase
전통적인 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함 (true | false, default : false)
setting 엘리먼트의 예제이다:
name="cacheEnabled" value="true"/>
name="lazyLoadingEnabled" value="true"/>
name="multipleResultSetsEnabled" value="true"/>
name="useColumnLabel" value="true"/>
name="useGeneratedKeys" value="false"/>
name="autoMappingBehavior" value="PARTIAL"/>
name="autoMappingUnknownColumnBehavior" value="WARNING"/>
name="defaultExecutorType" value="SIMPLE"/>
name="defaultStatementTimeout" value="25"/>
name="defaultFetchSize" value="100"/>
name="safeRowBoundsEnabled" value="false"/>
name="mapUnderscoreToCamelCase" value="false"/>
name="localCacheScope" value="SESSION"/>
name="jdbcTypeForNull" value="OTHER"/>
name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
mapUnderscoreToCamelCase
전통적인 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함 (true | false, default : false)
name="cacheEnabled" value="true"/> name="lazyLoadingEnabled" value="true"/> name="multipleResultSetsEnabled" value="true"/> name="useColumnLabel" value="true"/> name="useGeneratedKeys" value="false"/> name="autoMappingBehavior" value="PARTIAL"/> name="autoMappingUnknownColumnBehavior" value="WARNING"/> name="defaultExecutorType" value="SIMPLE"/> name="defaultStatementTimeout" value="25"/> name="defaultFetchSize" value="100"/> name="safeRowBoundsEnabled" value="false"/> name="mapUnderscoreToCamelCase" value="false"/> name="localCacheScope" value="SESSION"/> name="jdbcTypeForNull" value="OTHER"/> name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
mybatis를 이용하여 여러 프로젝트를 진행하며, 매번 잊고 진행하는 정보가 있다.
바로 [mapUnderscoreToCamelCase]이다.
VO를 직접 생성하여 에 정의하여 사용하기도 하지만
결과값이 많을 경우 이를 다 적용하기엔 한계가 있다.
프로젝트를 진행하기 전에 환경설정 하는걸 잊지말자.
"머리가 나쁘면 손발이 고생한다."
[참고자료]
MyBatis, "mapUnderscoreToCamelCase", http://www.mybatis.org/mybatis-3/ko/configuration.html, (2016.10.20)
2016년 9월 22일 목요일
커스텀 이벤트, 상속
util.inherits(constructor, superConstructor)#
Inherit the prototype methods from one constructor into another. The prototype of
constructor
will be set to a new object created from superConstructor
.
As an additional convenience,
superConstructor
will be accessible through the constructor.super_
property.const util = require('util');
const EventEmitter = require('events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
MyStream.prototype.write = function(data) {
this.emit('data', data);
}
var stream = new MyStream();
console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true
stream.on('data', (data) => {
console.log(`Received data: "${data}"`);
})
stream.write('It works!'); // Received data: "It works!"
비동기식 함수 구현과 사용
- 비동기식 함수 구현
function addNum(num1, num2, callback) {
var res = num1 + num2;
callback(res);
}
- 비동기식 함수 사용
addNum(9, 23, function(res) {
alert('addNum Result : ' + res);
});
비동기식으로 동작하는 함수는 반환(return)을 이용해서 결과를 전달하지 않고 콜백(callback) 함수를 이용한다. 비동기 동작을 모두 마치면 callback 함수가 동작하면서, 그 결과가 콜백 함수의 파라미터로 전달된다.
* 비동기 코드를 사용할 때는, 동작의 결과를 콜백 함수의 파라미터로 입력한다.
2016년 8월 12일 금요일
애플리케이션 종료 막기
Event: 'uncaughtException'
The
'uncaughtException'
event is emitted when an exception bubbles all the way back to the event loop. By default, Node.js handles such exceptions by printing the stack trace to stderr and exiting. Adding a handler for the'uncaughtException'
event overrides this default behavior.
For example:
process.on('uncaughtException', (err) => {
console.log(`Caught exception: ${err}`);
});
setTimeout(() => {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
Warning: Using 'uncaughtException'
correctly
Note that
'uncaughtException'
is a crude mechanism for exception handling intended to be used only as a last resort. The event should not be used as an equivalent to On Error Resume Next
. Unhandled exceptions inherently mean that an application is in an undefined state. Attempting to resume application code without properly recovering from the exception can cause additional unforeseen and unpredictable issues.
Exceptions thrown from within the event handler will not be caught. Instead the process will exit with a non zero exit code and the stack trace will be printed. This is to avoid infinite recursion.
Attempting to resume normally after an uncaught exception can be similar to pulling out of the power cord when upgrading a computer -- nine out of ten times nothing happens - but the 10th time, the system becomes corrupted.
The correct use of
'uncaughtException'
is to perform synchronous cleanup of allocated resources (e.g. file descriptors, handles, etc) before shutting down the process. It is not safe to resume normal operation after 'uncaughtException'
.아무런 대응없이 허무하게 프로세스가 강제종료 되는 현상을 막을 수 있다.
커스텀 콘솔
Class: Console
The
Console
class can be used to create a simple logger with configurable output streams and can be accessed using either require('console').Console
or console.Console
:const Console = require('console').Console;
const Console = console.Console;
new Console(stdout[, stderr])
Creates a new
Console
by passing one or two writable stream instances. stdout
is a writable stream to print log or info output. stderr
is used for warning or error output. If stderr
isn't passed, warning and error output will be sent to stdout
.const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
var count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5
The global
new Console(process.stdout, process.stderr);console
is a special Console
whose output is sent to process.stdout
and process.stderr
. It is equivalent to calling:2016년 5월 9일 월요일
Javascript 반올림 처리
반올림 처리
Javascript에서 반올림 처리를 하고자 할 경우 두 가지 방법을 이용할 수 있다.
첫번째는 Math Object를 이용하는 방법이고, 두번째는 Number Object를 이용하는 방법이다.
하단 예제를 통해 그 차이점과 용도를 알아보자.
1) Math Object round() Method
Round a number to :the nearest integer
- var n = 41.925;
- alert(Math.round(n)); // 42
Math Object의 round()객체를 이용하여 반올림을 수행할 경우 소수점 자릿수 지정 불가
2) Number Object toFixed() Method
Convert a number into a string, keeping only two decimals:
- var n = 41.925;
- alert(n.toFixed(2)); // 41.93
number.toFixed(x) parameter x (Default 0)
피드 구독하기:
글 (Atom)