トッカンソフトウェア

AngularJS Component

今回は前回前々回で取り上げなかったComponentの機能をやります。
  1. bindings
  2. require
  3. transclude



bindings

bindingsはHTMLとコントローラを結びつけます。結びつける種類も幾つかあり、"@"、"&"、"="、"<"の記号を使って種類を指定します。
記号 説明
@ 文字列を連携します。
& メソッドを連携します。
= オブジェクトを連携します(双方向)。
< オブジェクトを連携します(片方向)。

bindings @

@は属性に指定された文字列を取得します。
				

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var testApp = angular.module("testApp", []);

function TestCtrl() {
	this.show = function(){
		return "---" + this.msg + "---";
	};
}

testApp.component("tag", {
	bindings: {
		msg: "@"
	},
	template: "<h1>" + "{{obj.show()}}" + "</h1>",
	controller: TestCtrl,
	controllerAs: "obj"

});
</script>
</head>
<body ng-app="testApp">
	<tag msg="Hello"></tag>
</body>
</html>



			
上記のサンプルプログラムを実行すると以下のようなソースに変換されます(bodyのみ抜き出し)。
				
<body ng-app="testApp" class="ng-scope">
	<tag msg="Hello" class="ng-isolate-scope"><h1 class="ng-binding">---Hello---</h1></tag>
</body>


			
実行イメージ


bindings &

&はメソッドを連携します。引数も渡せます。
				
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS parent</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var app = angular.module('parentApp', []);

function childCtrl() {
}

function parentCtrl() {
	this.show = function (msg) {
		alert("---" + msg + "---");
	};
}


app.component("child",  {
	bindings: {
		exec: "&"
	},
	template: '<button ng-click="chld.exec({message: \'Hello\'})">Click</button>',
	controller: childCtrl,
	controllerAs: "chld"
});

app.component("parent",  {
	template: '<child exec="prnt.show(message)"></child>',
	controller: parentCtrl,
	controllerAs: "prnt"
});

</script>
</head>
<body ng-app="parentApp">
	<parent></parent>
</body>
</html>


			

上記のサンプルプログラムを実行すると以下のようなソースに変換されます(bodyのみ抜き出し)。
				
<body ng-app="parentApp" class="ng-scope">
	<parent class="ng-isolate-scope">
		<child exec="prnt.show(message)" class="ng-isolate-scope">
			<button ng-click="chld.exec({message: 'Hello'})">Click</button>
		</child>
	</parent>
</body>


			
実行イメージ


bindings =

=はオブジェクトを連携します。どちらのオブジェクトを編集しても、もう片方に反映されます。
				

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS parent</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var app = angular.module('parentApp', []);

function childCtrl() {
}

function parentCtrl() {
	this.greeting = {
		word: "Hello"
	};
}

app.component("child",  {
	bindings: {
		obj: "="
	},
	template: '<h1>--- {{chld.obj.word}} ---</h1>',
	controller: childCtrl,
	controllerAs: "chld"
});

app.component("parent",  {
	template: '<child obj="prnt.greeting"></child>',
	controller: parentCtrl,
	controllerAs: "prnt"
});

</script>
</head>
<body ng-app="parentApp">
	<parent></parent>
</body>
</html>



			
上記のサンプルプログラムを実行すると以下のようなソースに変換されます(bodyのみ抜き出し)。
				
<body ng-app="parentApp" class="ng-scope">
	<parent class="ng-isolate-scope">
		<child obj="prnt.greeting" class="ng-isolate-scope">
			<h1 class="ng-binding">--- Hello ---</h1>
		</child>
	</parent>
</body>


			
実行イメージ


bindings <

< もオブジェクトを連携しますが、オブジェクトを編集したとき片方向のみ反映されます。
下のサンプルで< を= に変更して動作させると違いがわかります。
				
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS parent</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var app = angular.module('parentApp', []);

function childCtrl() {
	this.clickChld = function(){
		this.obj = {word:"Child Click !!"};
	};
}

function parentCtrl() {
	this.greeting = {
		word: "Hello World !!"
	};
	this.clickPrnt = function(){
		this.greeting = {word:"Parent Click !!"};
	};
}

app.component("child",  {
	bindings: {
		obj: "<"
	},
	template: '<input type="button" ng-click="chld.clickChld()" value="C" />' + 
		'<h2>{{chld.obj.word}}</h2>',
	controller: childCtrl,
	controllerAs: "chld"
});

app.component("parent",  {
	template: '<input type="button" ng-click="prnt.clickPrnt()" value="P" />' + 
		'<h1>{{prnt.greeting.word}}</h1>' + 
		'<child obj="prnt.greeting"></child>',
	controller: parentCtrl,
	controllerAs: "prnt"
});

</script>
</head>
<body ng-app="parentApp">
	<parent></parent>
</body>
</html>


			
上記のサンプルプログラムを実行すると以下のようなソースに変換されます(bodyのみ抜き出し)。
				
<body ng-app="parentApp" class="ng-scope">
	<parent class="ng-isolate-scope">
		<input type="button" ng-click="prnt.clickPrnt()" value="P">
		<h1 class="ng-binding">Hello World !!</h1>
		<child obj="prnt.greeting" class="ng-isolate-scope">
			<input type="button" ng-click="chld.clickChld()" value="C">
			<h2 class="ng-binding">Hello World !!</h2>
		</child>
	</parent>
</body>


			
実行イメージ

Pボタンを押すと、上下のメッセージが「Parent Click !!」に変わりますが、Cボタンを押すと下のメッセージしか「Child Click !!」に変わりません。
< を= に変更すると、どちらのボタンを押しても両方のメッセージが変わります。


ページのトップへ戻る

require

requireプロパティを使うと、他のコントロールと連携できます。bindings <のサンプルを少し変えてみました。
				
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS parent</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var app = angular.module('parentApp', []);

function childCtrl() {
	this.clickChld = function(){
		this.obj = { word : this.prntCtrl.greeting.word };
	};
}

function parentCtrl() {
	this.greeting = {
		word: "Hello World !!"
	};
	this.clickPrnt = function(){
		this.greeting = { word : "Parent Click !!" };
	};
}

app.component("child",  {
	require: {
		prntCtrl: '^parent'
	},
	template: '<input type="button" ng-click="chld.clickChld()" value="C" />' + 
		'<h2>{{chld.obj.word}}</h2>',
	controller: childCtrl,
	controllerAs: "chld"
});

app.component("parent",  {
	template: '<input type="button" ng-click="prnt.clickPrnt()" value="P" />' + 
		'<h1>{{prnt.greeting.word}}</h1>' + 
		'<child obj="prnt.greeting"></child>',
	controller: parentCtrl,
	controllerAs: "prnt"
});

</script>
</head>
<body ng-app="parentApp">
	<parent></parent>
</body>
</html>


			


サンプルではprntコントロールをchldコントロールが参照できるようにしています。

Pボタンを押す前にCボタンを押すと「Hello World !!」が表示され、Pボタンを押した後にCボタンを押すと「Parent Click !!」が表示されます。

requireの頭で^を付けているのは、親から探すという指定になります。


ページのトップへ戻る

transclude

transcludeにtrueを設定すると、componentで指定した要素より下を保持し、指定した場所に出力できるようにします。
				
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AngularJS Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<!-- script src="angular.min.js"></script -->
<script>

var testApp = angular.module("testApp", []);

testApp.component("hello", {
	transclude: true,
	template: "<h1>Hello <span ng-transclude></span> <span ng-transclude></span></h1>"
});

</script>
</head>
<body ng-app="testApp">
	<hello>World!!</hello>
</body>
</html>


			


省略した場合、falseが設定されたことになり、componentで指定した要素の下は置き換えられます。
上の例ではHelloだけが表示された状態になります。



ページのトップへ戻る