AngularJS初識--作用域

作用域是構成AngularJS應用的核心基礎,在整個框架中都被廣泛使用。作用域是視圖和控制器之間的膠水。在應用將視圖渲染並呈現個用戶之前,視圖中的模板和作用域進行連接,然後應用會對DOM進行設置以便將屬性變化通知給AngularJS。也就是說,作用域是應用狀態的基礎。基於動態綁定,我們可以依賴視圖在修改數據時立即更新$scope,也可以依賴$scope在其發生改變時立刻重新渲染視圖

  • 以下方式會創建新的子作用域,並且進行原型繼承ng-repeat ng-include ng-switch ng-view ng-controller scope:truetransclude:true 創建directive

在創建子作用域後,關於屬性方法等的查找像js原型鏈繼承類似。如果子作用域中不存在該屬性,會在父作用域中查找,如果不存在,則在子作用域中創建該屬性。但是ng-repeat會對每一個迭代項item都會創建子作用域,子作用域也從父作用域進行原型繼承。但它還是會在子作用域中新建同名屬性,把item賦值給對應的子作用域的同名屬性

  • 以下方式會創建獨立作用域,不會進行原型繼承:用scope: {…}創建directive,這樣創建的作用域被稱爲“隔離作用域”。默認情況下創建directive使用了scope:false,不會創建子作用域

  • 如果一個scope 不存在於元素上,那麼它將繼承它的父級scope

    <div ng-controller = "MyController">
        <h1>{{clock}}</h1>
    </div>
    

    在script腳本里編寫控制器函數

    var app = angular.module('myapp',[]);
    app.controller("MyController",function($scope,$timeout){
        var updateClock = function(){
            $scope.clock = new Date();
            $timeout(function(){
                updateClock();
            },1000)
        };
        updateClock();
    })
    
  • 如果一個元素不是某個ng-app的一部分,那麼它不屬於任何scope。

AngularJS啓動並生成視圖時,會將根ng-app元素同 $rootScope 進行綁定。$rootScope 是所有 $scope 對象的最上層。$scope 對象就是一個普通的JavaScript對象,存在於AngularJS中的控制層。我們可以在其上隨意修改或添加屬性。 $scope 對象在AngularJS中充當數據模型,但與傳統的數據模型不一樣,$scope 並不負責處理和操作數據,它只是視圖和HTML之間的橋樑,它是視圖和控制器之間的膠水。$scope 的所有屬性都可以自動被視圖訪問到。

    <div ng-controller='ParentController'>
    <p>we can access :{{rootProperty}} and {{parentProperty}}</p>
    <div ng-controller="ChildController">
        <p>we can access: {{rootProperty}} and {{parentProperty}} and {{childProperty}}</p>
        <p>{{fullSentenceFromChild}}</p>
    </div>

</div>

添加控制器函數

var app = angular.module('myapp',[]);
//run訪問$rootScope屬性和方法
app.run(function($rootScope){
        $rootScope.rootProperty = 'root scope';
    })

    app.controller('ParentController',function($scope){
        $scope.parentProperty = 'partent scope';

    })
    app.controller('ChildController',function($scope){
        $scope.childProperty = 'child scope';
        $scope.fullSentenceFromChild = 'Same $scope:we can access:'+ $scope.rootProperty + 'and' + $scope.parentProperty + 'and' + $scope.childProperty;

    })

運行結果如下
這裏寫圖片描述

scope內部屬性

打開Chrome並導航到正在使用的一個angular應用程序,審查元素並打開開發者工具。我們知道$0 可以獲得最後一個選中的元素,$1 訪問前一個被選中的元素。在控制檯中輸入命令

angular.element($0).scope()

這裏寫圖片描述

下面是該命令產生的屬性

  • $id: scope的唯一標識符
  • $root: 根scope
  • $parent: 父級scope,如果scope == scope.$root 則爲null
  • $$childHead: 第一個子scope,如果沒有則爲null
  • $$childTail: 最後一個子scope,如果沒有則爲null
  • $$prevSibling: 前一個相鄰節點scope,如果沒有則爲null
  • $$nextSibling: 後一個相鄰節點scope,如果沒有則爲null

scope與事件的傳播

使用scope可以綁定事件和發佈事件,angular中發送事件可以使用$emit(向上發送事件)、$broadcast(向下發送事件)$on來綁定事件

<div ng-controller="parentCtrl">
    <div ng-controller='selfCtrl'>
        <span class='btn' ng-click='click()'>click me</span>
        <div ng-controller='childCtrl'></div>
    </div>
    <div ng-controller='broCtrl'></div>
</div>
<script type="text/javascript">
    var app = angular.module('myapp',[]);
    app.controller('parentCtrl',function($scope){
        $scope.$on('to-parent',function(e,d){
            console.log('topartent'+d);
        })
    })
    app.controller('selfCtrl',function($scope){    
        $scope.$on('to-child',function(e,d){
            console.log('toChild+child'+d);
        })
        $scope.click = function(){

            $scope.$broadcast('to-child','haha');
            $scope.$emit('to-parent','hehe');
        }
    })
    app.controller('childCtrl',function($scope){
        $scope.$on('to-child',function(e,d){
            console.log('toChild+child'+d);
        })
    })
    app.controller('broCtrl',function($scope){
        $scope.$on('to-child',function(e,d){
            console.log('toChildbto'+d);
        })
    })
</script>

具體實現代碼請參看github scope與事件傳播
最後總結scope的特點

  • $scope是一個普通的js對象(pojo)
  • $scope提供了一些工具方法,如$watch$apply
  • $scope 是表達式的執行環境
  • $scope 是一個樹形結構,與DOM標籤平行,並且能夠訪問父類的屬性和方法
  • 每一個Angular運行環境中都有根作用域,一般位於ng-app所定義的節點上
  • $scope 可以傳播書劍,類似DOM事件,可以向上傳播($emit),也可以向下傳播($broadcast
  • 可以通過angular.element($0).scope()進行調試
發佈了81 篇原創文章 · 獲贊 24 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章