1. 程式人生 > >angular中作用域的問題

angular中作用域的問題

一,angular中的$scope與this的區別。

1,引用方式的不同。

首先看一段程式碼:

<!DOCTYPE html>
<html ng-app='myapp'>
<head>
  <meta charset="UTF-8">
    <title>angular 中的作用域</title>
    <script src="./bower_components/angular/angular.js"></script>
</head>
<body>
  <div
ng-controller='scopeCtrl' ng-cloak>
{{test}} </div> <div ng-controller='thisCtrl as vm' ng-cloak> {{vm.test}} </div> <script> angular.module('myapp', []) .controller('scopeCtrl', ['$scope', function($scope){ $scope.test = 'hello'
; }]) .controller('thisCtrl', ['$scope', function($scope){ this.test = 'world'; }]);
</script> </body> </html>

scopeCtrl 控制器中test 變數是 $scope 的一個屬性,所以在html中引用直接引用即可,即使用 {{test}} 便可以獲得相應的值。

thisCtrl 控制器中 test 變數是 this 的屬性,在html中引用需要連同控制器名一起加上,即 {{vm.test}}

才能獲得相應的值。值得注意的是必須使用 controller as ... 的語法,才能引用到 test 的值,例如單純使用 {{thisCtrl.test}} 是不能獲得 test 的值的。具體原因還不清楚。

2,作用域繼承的不同。

子控制器能夠訪問到父控制器中 $scope 的資料。但是不能訪問到父控制器中 this 的資料。例如一下程式碼段:

  <div ng-controller='scopeCtrl' ng-cloak>
    {{test}}
    <div ng-controller='scopeChild'>
        {{test}}
    </div>
  </div>
  <div ng-controller='thisCtrl as vm' ng-cloak>
    {{vm.test}}
    <div ng-controller='thisChild as child'>
        {{child.test}}
    </div>
  </div>
<script>
        angular.module('myapp', [])
        .controller('scopeCtrl', ['$scope', function($scope){
            $scope.test = 'hello';
        }])
        .controller('thisCtrl', ['$scope', function($scope){
            this.test = 'world';
        }])
        .controller('scopeChild', ['$scope', function($scope){
        }])
        .controller('thisChild', ['$scope', function($scope){
        }]);
    </script>

以上程式碼中scopeChild 下的test能獲得scopeCtrl 中test的值。但是 thisChild 下的child.test就不能獲得thisCtrl 中test的值。

二,angular中$scope作用域的繼承。

1,非物件資料的繼承。

一般情況下,子作用域能夠繼承父作用域中 $scope 基本型別的值(前提是子作用於中沒有重新定義父作用域中的值)。看下面的程式碼:

<!DOCTYPE html>
<html ng-app='myapp'>
<head>
  <meta charset="UTF-8">
    <title>angular 中的作用域</title>
    <script src="./bower_components/angular/angular.js"></script>
</head>
<body>
  <div ng-controller='parentCtrl'>
    <label>父作用域</label>
    <input type="text" name="parent" ng-model='name'>
    <div ng-controller='childCtrl'>
        <label>子作用域</label>
        <input type="text" name="child" ng-model='name'>
    </div>
  </div>
    <script>
        angular.module('myapp', [])
        .controller('parentCtrl', ['$scope', function($scope){
            $scope.name = 'hu';
        }])
        .controller('childCtrl', ['$scope', function($scope){
        }]);
    </script>
</body>
</html>

在以上程式碼中,在不向子作用域對應的輸入框輸入之前,在父作用域對應的輸入框更改值時,子作用域也會跟著改變。這是因為子作用域中沒用name 屬性,當要對其求值時就在父作用域中查詢。

如果我們在子作用域對應的輸入框上做更改,父作用域對應的輸入框不會有改變,這是理所應當的,因為父作用域不會繼承子作用域。但是之後再更改父作用域輸入框的值時,子作用域輸入框的值就不再改變了。原因是當我們更改了子作用域輸入框的值時,實際上是在子作用域中$scope 上建立了一個與父作用域同名的屬性,之後子作用域的該屬性就不再繼承父作用域的屬性了。

2,物件資料的繼承。

物件的繼承是按引用傳值的,也就是說子作用域中的物件是與父作用域中某個物件是同一個物件。這樣,無論是修改父作用域中的值還是修改子作用域中的值,另外一個值也會相應做出改變。部分程式碼如下:

<div ng-controller='parentCtrl'>
    <label>父作用域</label>
    <input type="text" name="parent" ng-model='obj.name'>
    <div ng-controller='childCtrl'>
        <label>子作用域</label>
        <input type="text" name="child" ng-model='obj.name'>
    </div>
  </div>
<script>
        angular.module('myapp', [])
        .controller('parentCtrl', ['$scope', function($scope){
            $scope.obj = {}
            $scope.obj.name = 'hu';
        }])
        .controller('childCtrl', ['$scope', function($scope){
        }]);
    </script>