Webエンジニア susumuis の技術ブログ

このブログの内容は個人の見解であり、所属する組織の公式見解ではありません

JavaScript テンプレートエンジン #3 (Loop実装)

さらに続きです。

今日はループを実装してみました。

TemplateEngine = new function() {
	var currentNode;
	
	this.setCurrentNode = setCurrentNode;
	this.writeText = function (value) { return new WriteText(value); };
	this.writeHtml = function (value) { return new WriteHtml(value); };
	this.setAttribute = function (name, value) { return new SetAttribute(name, value); };
	this.loopWhile = function(condition) { return new LoopWhile(condition); }
	
	function setCurrentNode(node) {
		currentNode = node;
	}
	
	function WriteText(value) {
		this.execute = execute;
		function execute() {
			currentNode.text(value);
		}
	}
	function WriteHtml(value) {
		this.value = value;
		this.execute = execute;
		function execute() {
			currentNode.html(value);
		}
	}
	function SetAttribute(name, value) {
		this.execute = execute;
		function execute() {
			currentNode.attr(name, value);
		}
	}
	function LoopWhile(condition) {
		this.execute = execute;
		function execute() {
			while (condition()) {
				var clone = currentNode.clone(true);
				clone.insertAfter(currentNode);
			}
		}
	}
}

TemplateEngineRunner = new function() {
	this.run = run;

	function run(controller) {
		for (var key in controller) {
			TemplateEngine.setCurrentNode($('#' + key));
			controller[key].execute();
		}
	}
}
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>Template Engine Test</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<span id="test"></span>
<span id="testHtml"></span>
<span id="attr">test</span>
<span id="loop">loop</span>

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.4.2");</script>
<script type="text/javascript" src="templateEngine.js"></script>  
<script>
	with (TemplateEngine) {
		var i = 0;
		var controller = {
			test: writeText('hoge<b>aaa</b>'),
			testHtml: writeHtml('<i>aaa</i>'),
			attr: setAttribute('style', 'font-weight: bold;'),
			loop: loopWhile(function() {return i++ < 10;})
		}
	}
	
	TemplateEngineRunner.run(controller);
</script>
</body>
</html>

出力結果

hogeaaa aaa test looplooplooplooplooplooplooplooplooplooploop


ループしながらそれぞれの要素をどうにかしないといけないのと、このままでは同じidが複数できてしまってDOM的にNGなのが気になります。が、そろそろ色々できるようになってきたので、GitHubあたりで公開したほうがいいでしょうか?とすると、プロジェクト名とか決めなきゃいけないですね。募集します(笑)

ループのネスト実装したけど

これじゃいけてないよね?

	with (TemplateEngine) {
		var i = 0;
		var data = {};
		var controller = {
			test: writeText(function() {return 'hoge<b>aaa</b>'}),
			testHtml: writeHtml(function() {return '<i>aaa</i>';}),
			attr: setAttribute('style', function() {return 'font-weight: bold;'}),
			loop: loopWhile(
				function() {return i++ < 10;},
				{
					counter: writeText(function() {return i;})
				}
			),
			'for': loopFor(
				function() {i = 0},
				function() {return i < 3},
				function() {i++;},
				{
					counterFor: writeText(function() {return i;})
				}
			)
		}
	}

まあ、でも、Mayaaで言うところの、${}が、function() {}に相当するから、仕方ないのかなこれは。

追記(疑問)

ところで、クラスのprivateにvarを、publicにthisを使うような使い分けを上記のようにやってるんだけど、この書き方って、一般的?

続き→http://d.hatena.ne.jp/s-ishigami/20101119/1290151078