前篇介紹過ng-if,動態決定是否產生DOM區塊,NG還有另一項工具 – ngSwitch!
<!DOCTYPEhtml>
<htmlng-app="sampleApp">
<head>
<metacharset="utf-8">
<title>ng-switch範例</title>
<style>
.sw > div { padding: 6px; margin: 6px; }
</style>
</head>
<bodyng-controller="defaultCtrl">
<selectng-model="model.view">
<option>A</option><option>B</option><option>C</option>
</select>
propA = {{propA}} model.propB = {{model.propB}}
<divng-switch="model.view"class="sw">
<divng-switch-when="A">
View A / propA={{propA}} propB={{model.propB}}
</div>
<divng-switch-when="B">
View B / <br/>
propA <inputng-model="propA"/><br/>
propB <inputng-model="model.propB"/>
</div>
<divng-switch-default>
View C
</div>
</div>
<scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js"></script>
<script>
angular.module("sampleApp", [])
.controller("defaultCtrl", function($scope) {
function myViewModel() {
var self = this;
self.view = "A";
self.propB = "Boo";
}
$scope.propA = "Foo";
$scope.model = new myViewModel();
});
</script>
</body>
</html>
ngSwitch用法如上,在容器加上ng-switch="屬性",用ng-switch-when="特定值"控制子元素是否顯示。切換下拉選單,下方會分別顯示View A、View B或View C。在此範例中,我額外加了propA及propB用來突顯NG的Scope繼承特性。propA直屬$scope,而propB屬於$scope.model,在View B用兩個<input> ng-model繫結,允許使用者修改propA及propB。
當使用某些Directive(包含: ng-repeat, ng-include, ng-switch, ng-view, ng-controller,或是其他scope: true或transclude: true的自訂Directive),NG會為其建立一個新Scope並繼承父容器Scope的屬性。以前述程式為例,每當ng-switch-when="A"及ng-switch-when="B"成立要顯示<div>時,NG會建立新Scope,並繼承父容器Scope自動加入兩個屬性: propA(字串)以及propB(物件)。propA是字串(屬Primitive原始型別)、propB則是JavaScript物件,如同C# Value Type與Reference Type間的差異,父Scope與新Scope的propA是兩個字串,propB卻指向同一個物件。切到View B,動手修改propA及propB,可發現最上方的propA不受影響,propB跟著連動,證明父Scope.propA與View B Scope.propA是兩個獨立物件,而父Scope.model與View B Scope.model則指向相同物件。
另外還有一個重要觀念,為View B建立的新Scope在切換到View A或View C後便消失,下次再切回View B時,會再產生另一個新Scope。在View B將propA改成FooX,切到View C再切回View B,propA又變回Foo,驗證剛才的修改已隨風而逝。
NG的Scope繼承行為,常把初學者耍得團團轉直呼見鬼,為此官方特別寫了一份文件(Understanding Scopes · angular-angular.js Wiki)做了詳細解釋,值得一讀。