標籤:
最近在Angular項目中遇到關於controller內使用$scope&this 暴露資料的問題,下面來分析一下:
"controller as" 是Angular在1.2版本後新增的語法,我將從引用方式,作用範圍,對象對比三個方面做兩者的比較:
引用方式:
1) $scope 只需要在注入中聲明,後面就可以直接在附加資料對象:
controller:
function ACtrl($scope) {
$scope.test = "一個例子"; //在$scope對象中加入test
}
html:
<div ng-controller="ACtrl">
{{test}}
</div>
2) this 則採用了controller as(需要版本為ng 1.2+)寫法:
controller:
function BCtrl() {
var vm = this;
this.test = "一個例子"; //在this對象中加入test
}
html:
<!-- vm為自己為當前控制器作的一個簡略記號,也可以寫作 BCtrl as b,
後面變數便可以在b中引出 如b.test -->
<div ng-controller="BCtrl as vm">
{{vm.test}}
</div>
作用範圍:
1) $scope 中的變數或資料對象我們可以全部拿到,並且上級控制器中的變數也可以在下級控制器中被擷取到:
controller:
function ParentCtrl($scope) {
$scope.test = "測試";
$scope.cover ="覆蓋測試";
}
function ChildCtrl($scope) {
$scope.cover ="子覆蓋測試";
var test = $scope.test; //“測試”
}
html:
<div ng-controller="ParentCtrl">
<p>Parent-test : {{test}}</p>
<p>Parent-cover : {{cover}}</p>
<div ng-controller="ChildCtrl">
<p>Child-test : {{test}}</p>
<p>Child-cover : {{cover}}</p>
</div>
</div>
我在父控制器ParentCtrl中聲明的test變數並未在子控制器ChildCtrl中做聲明,而在ChildCtrl作用範圍內的Child-test 中,test卻輸出了”測試”;基於此我再做了一次覆蓋測試,檢測結果顯示,當父子控制器同時存在相同的變數時, 父子控制器各自範圍內的值不會被覆蓋;
2) this 中的變數則只適用於當前控制器:
controller:
function ParentCtrl($scope) {
var vm = this;
vm.test = "測試";
vm.cover ="覆蓋測試";
}
function ChildCtrl($scope) {
var vm = this;
vm.cover ="子覆蓋測試";
}
html:
<div ng-controller="ParentCtrl as parent">
<p>Parent-test : {{parent.test}}</p>
<p>Parent-cover : {{parent.cover}}</p>
<div ng-controller="ChildCtrl as child">
<p>Child-test : {{child.test}}</p>
<p>Child-cover : {{child.cover}}</p>
</div>
<div ng-controller="ChildCtrl as parent">
<p>Child-test : {{parent.test}}</p>
<p>Child-cover : {{parent.cover}}</p>
</div>
</div>
在使用this的時候,各層級變數的命名空間是平行的狀態,模板html中只可以拿到當前控制器下聲明的變數。
對象對比:
controller:
function CCtrl($scope) {
var vm = this;
$scope.logThisAndScope = function() {
console.log(vm === $scope)
}
}
vm與$scope實際上是不相等的,在console中我們可以看到
vm: Constructor;
$scope: $get.Scope.$new.Child;
而在$scope中又包含了一個變數vm: Constructor
實際結構是
$scope: {
...,
vm: Constructor,
...
}
那麼我們可以整理如下:
$scope 當控制器在寫法上形成父子級關係時,子級沒有的變數或方法父級會自動強加在子級身上,子級可以任意擷取到當前父級的變數或方法,該種形式是無法復原的,即父級無法通過$scope擷取到子級的任意變數或方法。
this 則像一個獨立的個體,所有東西都是由自己管理,也就不存在父子級變數混淆關係了。
那資料共用該如何進行呢?資料商務邏輯我覺得還是交給更專業的service來處理吧。
兩種方式其實在效能上並無優劣之分,只有代碼習慣的選擇。
這或許可以取決於我們觀察的角度,其實可以理解為私用跟公用的區別!
this與$scope